Fixed segfault because of out-of-bounds access to a vector, changed index operator to at() to prevent similar problems in future

This commit is contained in:
codedokode 2018-08-12 01:15:53 +03:00
parent 45b752b130
commit b06aeb812d
1 changed files with 26 additions and 16 deletions

View File

@ -122,6 +122,7 @@ Bool XKeyboard::initializeXkb()
_groupNames.push_back(""); _groupNames.push_back("");
} else { } else {
groupName = groupNameC; groupName = groupNameC;
// Remove everything after a brace, e.g. "English(US)" -> "English"
std::string::size_type pos = groupName.find('(', 0); std::string::size_type pos = groupName.find('(', 0);
if (pos != std::string::npos) { if (pos != std::string::npos) {
groupName = groupName.substr(0, pos - 1); groupName = groupName.substr(0, pos - 1);
@ -147,25 +148,34 @@ Bool XKeyboard::initializeXkb()
} }
XkbSymbolParser symParser; XkbSymbolParser symParser;
// Parser is supposed to extract layout symbols (like us, de, ru)
// and variants (like dvorak) from symName string. But sometimes
// it gets nothing, for example on my system with Xwayland symName
// is "(unnamed)" and both _symbolNames and _variantNames are empty.
symParser.parse(symName, _symbolNames, _variantNames); symParser.parse(symName, _symbolNames, _variantNames);
int count = _symbolNames.size(); int symNameCount = _symbolNames.size();
if (count == 1 && _groupNames[0].empty() && _symbolNames[0] == "jp") {
if (symNameCount == 1 && _groupNames[0].empty() && _symbolNames[0] == "jp") {
_groupCount = 2; _groupCount = 2;
_symbolNames.resize(_groupCount);
_groupNames.resize(_groupCount);
_symbolNames[1] = _symbolNames[0]; _symbolNames[1] = _symbolNames[0];
_symbolNames[0] = "us"; _symbolNames[0] = "us";
_groupNames[0] = "US/ASCII"; _groupNames[0] = "US/ASCII";
_groupNames[1] = "Japanese"; _groupNames[1] = "Japanese";
} else { } else {
if (count < _groupCount) { // If there are less symbol names, than groups,
int j = count; // fill remaining with default name of "en_US".
int k = _groupCount; if (symNameCount < _groupCount) {
while (--j >= 0) _symbolNames[--k] = _symbolNames[j]; while (_symbolNames.size() < (size_t)_groupCount) {
while (--k >= 0) _symbolNames[k] = "en_US"; _symbolNames.insert(_symbolNames.begin(), "en_US");
}
} }
} }
count = _groupNames.size(); int groupNameCount = _groupNames.size();
for (int i = 0; i < count; i++) { for (int i = 0; i < groupNameCount; i++) {
if (_groupNames[i].empty()) { if (_groupNames[i].empty()) {
std::string name = getSymbolNameByResNum(i); std::string name = getSymbolNameByResNum(i);
if (name.empty()) { if (name.empty()) {
@ -186,12 +196,12 @@ Bool XKeyboard::initializeXkb()
std::string XKeyboard::getSymbolNameByResNum(int groupResNum) std::string XKeyboard::getSymbolNameByResNum(int groupResNum)
{ {
return _symbolNames[groupNumResToXkb(groupResNum)]; return _symbolNames.at(groupNumResToXkb(groupResNum));
} }
std::string XKeyboard::getGroupNameByResNum(int groupResNum) std::string XKeyboard::getGroupNameByResNum(int groupResNum)
{ {
return _groupNames[groupNumResToXkb(groupResNum)]; return _groupNames.at(groupNumResToXkb(groupResNum));
} }
int XKeyboard::groupNumResToXkb(int groupResNum) int XKeyboard::groupNumResToXkb(int groupResNum)
@ -201,13 +211,13 @@ int XKeyboard::groupNumResToXkb(int groupResNum)
int XKeyboard::groupLookup(int srcValue, StringVector fromText, StringVector toText, int count) int XKeyboard::groupLookup(int srcValue, StringVector fromText, StringVector toText, int count)
{ {
const std::string srcText = fromText[srcValue]; const std::string srcText = fromText.at(srcValue);
if (!srcText.empty()) { if (!srcText.empty()) {
std::string targetText; std::string targetText;
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
targetText = toText[i]; targetText = toText.at(i);
if (compareNoCase(srcText, targetText) == 0) { if (compareNoCase(srcText, targetText) == 0) {
srcValue = i; srcValue = i;
break; break;
@ -261,17 +271,17 @@ int XKeyboard::currentGroupNum() const
std::string XKeyboard::currentGroupName() const std::string XKeyboard::currentGroupName() const
{ {
return _groupNames[currentGroupNum()]; return _groupNames.at(currentGroupNum());
} }
std::string XKeyboard::currentGroupSymbol() const std::string XKeyboard::currentGroupSymbol() const
{ {
return _symbolNames[currentGroupNum()]; return _symbolNames.at(currentGroupNum());
} }
std::string XKeyboard::currentGroupVariant() const std::string XKeyboard::currentGroupVariant() const
{ {
return _variantNames[currentGroupNum()]; return _variantNames.at(currentGroupNum());
} }
bool XKeyboard::setGroupByNum(int groupNum) bool XKeyboard::setGroupByNum(int groupNum)