From 4401132836fdb8798c4dbe07b5c7ae1e0112f248 Mon Sep 17 00:00:00 2001 From: "Lubomir I. Ivanov" Date: Thu, 7 Mar 2013 21:16:31 +0200 Subject: Fix potentially broken white space truncation on certain Windows versions Testing the Planner in Subsurface on a Windows XP SP3 installation, shows corrupted UTF-8 strings in the case of Cyrillic locales, but possibly others as well. Instead limited to the Planner, this affects the entire application. After some examination it appears that 's isspace() in MSVC on the tested version of Windows is broken for some UTF-8 characters, after enabling the user locale using: setlocale(LC_ALL, ""); For example, characters such as the Cyrillic capital "BE" are defined as: 0xD091, where isspace() for the first byte returns 0x08, which is the bytemask for C1_SPACE and the character is treated as space. After a byte is treated as space, it is usually discarded from a UTF-8 character/string, where if only one byte left, corrupting the entire string. In Subsurface, usages of string trimming are present in multiple locations, so to make this work try to use GLib's g_ascii_isspace(), which is a locale agnostic version of isspace(). Affected versions of Windows could be everything up to XP SP3, but not apparently Vista. Reported-by: Sergey Starosek Signed-off-by: Lubomir I. Ivanov Signed-off-by: Dirk Hohndel --- info.c | 6 +++--- parse-xml.c | 8 ++++---- planner.c | 24 ++++++++++++------------ save-xml.c | 4 ++-- 4 files changed, 21 insertions(+), 21 deletions(-) diff --git a/info.c b/info.c index 0517eaccb..4a4b41c7d 100644 --- a/info.c +++ b/info.c @@ -48,7 +48,7 @@ static int text_changed(const char *old, const char *new) static const char *skip_space(const char *str) { if (str) { - while (isspace(*str)) + while (g_ascii_isspace(*str)) str++; if (!*str) str = NULL; @@ -82,7 +82,7 @@ static char *get_combo_box_entry_text(GtkComboBox *combo_box, char **textp, cons return NULL; new = get_active_text(combo_box); - while (isspace(*new)) + while (g_ascii_isspace(*new)) new++; /* If the master string didn't change, don't change other dives either! */ if (!text_changed(master,new)) @@ -724,7 +724,7 @@ static gboolean gps_entry_change_cb(GtkEntry *gps, GdkEvent *event, gpointer use } /* Otherwise, check if it's all empty.. */ - while (isspace(*string)) + while (g_ascii_isspace(*string)) string++; location_update.set_by_hand = !!*string; diff --git a/parse-xml.c b/parse-xml.c index bd22ad018..a5b2f5cee 100644 --- a/parse-xml.c +++ b/parse-xml.c @@ -386,7 +386,7 @@ static void percent(char *buffer, void *_fraction) case FLOAT: /* Turn fractions into percent unless explicit.. */ if (val <= 1.0) { - while (isspace(*end)) + while (g_ascii_isspace(*end)) end++; if (*end != '%') val *= 100; @@ -437,10 +437,10 @@ static void utf8_string(char *buffer, void *_res) { int size; char *res; - while (isspace(*buffer)) + while (g_ascii_isspace(*buffer)) buffer++; size = strlen(buffer); - while (size && isspace(buffer[size-1])) + while (size && g_ascii_isspace(buffer[size-1])) size--; if (!size) return; @@ -926,7 +926,7 @@ static degrees_t parse_degrees(char *buf, char **end) int sign = 1, decimals = 6, value = 0; degrees_t ret; - while (isspace(*buf)) + while (g_ascii_isspace(*buf)) buf++; switch (*buf) { case '-': diff --git a/planner.c b/planner.c index d5a733e6e..b11cda138 100644 --- a/planner.c +++ b/planner.c @@ -789,7 +789,7 @@ static int validate_gas(const char *text, int *o2_p, int *he_p) if (!text) return 0; - while (isspace(*text)) + while (g_ascii_isspace(*text)) text++; if (!*text) @@ -806,7 +806,7 @@ static int validate_gas(const char *text, int *o2_p, int *he_p) } /* We don't want any extra crud */ - while (isspace(*text)) + while (g_ascii_isspace(*text)) text++; if (*text) return 0; @@ -829,14 +829,14 @@ static int validate_time(const char *text, int *sec_p, int *rel_p) if (!text) return 0; - while (isspace(*text)) + while (g_ascii_isspace(*text)) text++; rel = 0; if (*text == '+') { rel = 1; text++; - while (isspace(*text)) + while (g_ascii_isspace(*text)) text++; } @@ -873,7 +873,7 @@ static int validate_time(const char *text, int *sec_p, int *rel_p) } /* Maybe we should accept 'min' at the end? */ - if (isspace(*text)) + if (g_ascii_isspace(*text)) text++; if (*text) return 0; @@ -894,7 +894,7 @@ static int validate_depth(const char *text, int *mm_p) if (depth < 0) return 0; - while (isspace(*text)) + while (g_ascii_isspace(*text)) text++; imperial = get_units()->length == FEET; @@ -905,7 +905,7 @@ static int validate_depth(const char *text, int *mm_p) imperial = 1; text += 2; } - while (isspace(*text)) + while (g_ascii_isspace(*text)) text++; if (*text) return 0; @@ -933,10 +933,10 @@ static int validate_po2(const char *text, int *mbar_po2) if (po2 < 0) return 0; - while (isspace(*text)) + while (g_ascii_isspace(*text)) text++; - while (isspace(*text)) + while (g_ascii_isspace(*text)) text++; if (*text) return 0; @@ -956,7 +956,7 @@ static int validate_volume(const char *text, int *sac) if (volume < 0) return 0; - while (isspace(*text)) + while (g_ascii_isspace(*text)) text++; imperial = get_units()->volume == CUFT; @@ -967,11 +967,11 @@ static int validate_volume(const char *text, int *sac) imperial = 1; text += 4; } - while (isspace(*text) || *text == '/') + while (g_ascii_isspace(*text) || *text == '/') text++; if (!strncasecmp(text, _("min"), 3)) text += 3; - while (isspace(*text)) + while (g_ascii_isspace(*text)) text++; if (*text) return 0; diff --git a/save-xml.c b/save-xml.c index a23fb10a3..7ae71dd57 100644 --- a/save-xml.c +++ b/save-xml.c @@ -125,12 +125,12 @@ static void show_utf8(FILE *f, const char *text, const char *pre, const char *po if (!text) return; - while (isspace(*text)) + while (g_ascii_isspace(*text)) text++; len = strlen(text); if (!len) return; - while (len && isspace(text[len-1])) + while (len && g_ascii_isspace(text[len-1])) len--; /* FIXME! Quoting! */ fputs(pre, f); -- cgit v1.2.3-70-g09d2