fixed an access after free in OS_X11::set_context.

Added constructor and assignment operator for CharString
from const char* to simplify memory management when working with
utf8/ascii strings for APIs taking char*.
Reworked OS_X11::set_context to use CharString and avoid some manual
memory management.
This commit is contained in:
Ibrahn Sahir 2019-03-12 12:57:22 +00:00
parent 05dda9f87c
commit 9d0b3b300c
3 changed files with 55 additions and 19 deletions

View file

@ -123,6 +123,31 @@ const char *CharString::get_data() const {
return "";
}
CharString &CharString::operator=(const char *p_cstr) {
copy_from(p_cstr);
return *this;
}
void CharString::copy_from(const char *p_cstr) {
if (!p_cstr) {
resize(0);
return;
}
size_t len = strlen(p_cstr);
if (len == 0) {
resize(0);
return;
}
resize(len + 1); // include terminating null char
strcpy(ptrw(), p_cstr);
}
void String::copy_from(const char *p_cstr) {
if (!p_cstr) {

View file

@ -101,12 +101,17 @@ public:
_cowdata._ref(p_str._cowdata);
return *this;
}
_FORCE_INLINE_ CharString(const char *p_cstr) { copy_from(p_cstr); }
CharString &operator=(const char *p_cstr);
bool operator<(const CharString &p_right) const;
CharString &operator+=(char p_char);
int length() const { return size() ? size() - 1 : 0; }
const char *get_data() const;
operator const char *() const { return get_data(); };
protected:
void copy_from(const char *p_cstr);
};
typedef wchar_t CharType;

View file

@ -3036,34 +3036,40 @@ bool OS_X11::is_vsync_enabled() const {
*/
void OS_X11::set_context(int p_context) {
char *config_name = NULL;
XClassHint *classHint = XAllocClassHint();
if (classHint) {
char *wm_class = (char *)"Godot";
if (p_context == CONTEXT_EDITOR)
classHint->res_name = (char *)"Godot_Editor";
if (p_context == CONTEXT_PROJECTMAN)
classHint->res_name = (char *)"Godot_ProjectList";
if (p_context == CONTEXT_ENGINE) {
classHint->res_name = (char *)"Godot_Engine";
String config_name_tmp = GLOBAL_GET("application/config/name");
if (config_name_tmp.length() > 0) {
config_name = strdup(config_name_tmp.utf8().get_data());
} else {
config_name = strdup("Godot Engine");
}
wm_class = config_name;
CharString name_str;
switch (p_context) {
case CONTEXT_EDITOR:
name_str = "Godot_Editor";
break;
case CONTEXT_PROJECTMAN:
name_str = "Godot_ProjectList";
break;
case CONTEXT_ENGINE:
name_str = "Godot_Engine";
break;
}
classHint->res_class = wm_class;
CharString class_str;
if (p_context == CONTEXT_ENGINE) {
String config_name = GLOBAL_GET("application/config/name");
if (config_name.length() == 0) {
class_str = "Godot_Engine";
} else {
class_str = config_name.utf8();
}
} else {
class_str = "Godot";
}
classHint->res_class = class_str.ptrw();
classHint->res_name = name_str.ptrw();
XSetClassHint(x11_display, x11_window, classHint);
XFree(classHint);
free(config_name);
}
}