diff options
author | Lubomir I. Ivanov <neolit123@gmail.com> | 2013-03-07 21:16:31 +0200 |
---|---|---|
committer | Dirk Hohndel <dirk@hohndel.org> | 2013-03-07 12:01:47 -0800 |
commit | 4401132836fdb8798c4dbe07b5c7ae1e0112f248 (patch) | |
tree | 8739129e7ced876a95a013a05a0c64eaaee14ffe | |
parent | 9f6b8ca89a0d8828f2b60b01326f3bd9f021112c (diff) | |
download | subsurface-4401132836fdb8798c4dbe07b5c7ae1e0112f248.tar.gz |
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 <ctype>'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 <sergey.starosek@gmail.com>
Signed-off-by: Lubomir I. Ivanov <neolit123@gmail.com>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
-rw-r--r-- | info.c | 6 | ||||
-rw-r--r-- | parse-xml.c | 8 | ||||
-rw-r--r-- | planner.c | 24 | ||||
-rw-r--r-- | save-xml.c | 4 |
4 files changed, 21 insertions, 21 deletions
@@ -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 '-': @@ -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); |