BMenu: Use BUnicodeChar for unicode char manipulation.
It is not allowed to use isspace, tolower, etc, on character outside of the char type range (and EOF). Use BUnicodeChar instead to avoid out of bound accesses. Fixes the second crash in #14753. Signed-off-by: Augustin Cavalier <[email protected]> Some changes by me to make "index" a byte instead of character index as it needs to be.
This commit is contained in:
committed by
Augustin Cavalier
parent
c1917899cd
commit
588a0c9f67
+32
-20
@@ -1,10 +1,11 @@
|
||||
/*
|
||||
* Copyright 2001-2015 Haiku, Inc. All rights reserved.
|
||||
* Copyright 2001-2018 Haiku, Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT license.
|
||||
*
|
||||
* Authors:
|
||||
* Stephan Aßmus, [email protected]
|
||||
* Stefano Ceccherini, [email protected]
|
||||
* Adrien Destugues, [email protected]
|
||||
* Marc Flerackers, [email protected]
|
||||
* Rene Gollent, [email protected]
|
||||
* John Scipione, [email protected]
|
||||
@@ -15,6 +16,7 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <new>
|
||||
#include <set>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
@@ -35,6 +37,7 @@
|
||||
#include <Screen.h>
|
||||
#include <ScrollBar.h>
|
||||
#include <SystemCatalog.h>
|
||||
#include <UnicodeChar.h>
|
||||
#include <Window.h>
|
||||
|
||||
#include <AppServerLink.h>
|
||||
@@ -69,15 +72,17 @@ public:
|
||||
TriggerList() {}
|
||||
~TriggerList() {}
|
||||
|
||||
// TODO: make this work with Unicode characters!
|
||||
|
||||
bool HasTrigger(uint32 c)
|
||||
{ return fList.HasItem((void*)(addr_t)tolower(c)); }
|
||||
{ return fList.find(BUnicodeChar::ToLower(c)) != fList.end(); }
|
||||
|
||||
bool AddTrigger(uint32 c)
|
||||
{ return fList.AddItem((void*)(addr_t)tolower(c)); }
|
||||
{
|
||||
fList.insert(BUnicodeChar::ToLower(c));
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
BList fList;
|
||||
std::set<uint32> fList;
|
||||
};
|
||||
|
||||
|
||||
@@ -583,7 +588,7 @@ BMenu::KeyDown(const char* bytes, int32 numBytes)
|
||||
|
||||
default:
|
||||
{
|
||||
uint32 trigger = UTF8ToCharCode(&bytes);
|
||||
uint32 trigger = BUnicodeChar::FromUTF8(&bytes);
|
||||
|
||||
for (uint32 i = CountItems(); i-- > 0;) {
|
||||
BMenuItem* item = ItemAt(i);
|
||||
@@ -2870,27 +2875,34 @@ BMenu::_ChooseTrigger(const char* title, int32& index, uint32& trigger,
|
||||
if (title == NULL)
|
||||
return false;
|
||||
|
||||
index = 0;
|
||||
uint32 c;
|
||||
const char* nextCharacter, *character;
|
||||
|
||||
// two runs: first we look out for uppercase letters
|
||||
// TODO: support Unicode characters correctly!
|
||||
for (uint32 i = 0; (c = title[i]) != '\0'; i++) {
|
||||
if (!IsInsideGlyph(c) && isupper(c) && !triggers.HasTrigger(c)) {
|
||||
index = i;
|
||||
trigger = tolower(c);
|
||||
return triggers.AddTrigger(c);
|
||||
nextCharacter = title;
|
||||
character = nextCharacter;
|
||||
while ((c = BUnicodeChar::FromUTF8(&nextCharacter)) != 0) {
|
||||
if (!BUnicodeChar::IsUpper(c) || triggers.HasTrigger(c)) {
|
||||
character = nextCharacter;
|
||||
continue;
|
||||
}
|
||||
trigger = BUnicodeChar::ToLower(c);
|
||||
index = (int32)(character - title);
|
||||
return triggers.AddTrigger(c);
|
||||
}
|
||||
|
||||
// then, if we still haven't found anything, we accept them all
|
||||
index = 0;
|
||||
while ((c = UTF8ToCharCode(&title)) != 0) {
|
||||
if (!isspace(c) && !triggers.HasTrigger(c)) {
|
||||
trigger = tolower(c);
|
||||
return triggers.AddTrigger(c);
|
||||
nextCharacter = title;
|
||||
character = nextCharacter;
|
||||
while ((c = BUnicodeChar::FromUTF8(&nextCharacter)) != 0) {
|
||||
if (BUnicodeChar::IsSpace(c) || triggers.HasTrigger(c)) {
|
||||
character = nextCharacter;
|
||||
continue;
|
||||
}
|
||||
|
||||
index++;
|
||||
trigger = BUnicodeChar::ToLower(c);
|
||||
index = (int32)(character - title);
|
||||
return triggers.AddTrigger(c);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user