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:
parent
05dda9f87c
commit
9d0b3b300c
3 changed files with 55 additions and 19 deletions
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue