From e827eb8bdc797d2a8c194e675bd300e97aee6166 Mon Sep 17 00:00:00 2001 From: Cyrille Bagard Date: Fri, 4 Jan 2019 19:59:14 +0100 Subject: Handled non null-terminated strings --- plugins/pychrysalide/format/strsym.c | 10 ++-- src/format/strsym.c | 89 ++++++++++++++++++++++++++---------- src/format/strsym.h | 4 +- src/gui/panels/strings.c | 10 +++- 4 files changed, 80 insertions(+), 33 deletions(-) diff --git a/plugins/pychrysalide/format/strsym.c b/plugins/pychrysalide/format/strsym.c index 30224f8..8c210a2 100644 --- a/plugins/pychrysalide/format/strsym.c +++ b/plugins/pychrysalide/format/strsym.c @@ -73,12 +73,13 @@ static PyObject *py_string_symbol_get_raw(PyObject *self, void *closure) { PyObject *result; /* Valeur à retourner */ GStrSymbol *symbol; /* Elément à consulter */ + size_t len; /* Taille de la chaîne */ const char *data; /* Données à manipuler */ symbol = G_STR_SYMBOL(pygobject_get(self)); - data = g_string_symbol_get_raw(symbol); + data = g_string_symbol_get_raw(symbol, &len); - result = PyBytes_FromString(data); + result = PyBytes_FromStringAndSize(data, len); return result; @@ -102,12 +103,13 @@ static PyObject *py_string_symbol_get_utf8(PyObject *self, void *closure) { PyObject *result; /* Valeur à retourner */ GStrSymbol *symbol; /* Elément à consulter */ + size_t len; /* Taille de la chaîne */ const char *data; /* Données à manipuler */ symbol = G_STR_SYMBOL(pygobject_get(self)); - data = g_string_symbol_get_raw(symbol); + data = g_string_symbol_get_utf8(symbol, &len); - result = PyUnicode_FromString(data); + result = PyUnicode_FromStringAndSize(data, len); return result; diff --git a/src/format/strsym.c b/src/format/strsym.c index c921b9a..6feb8a1 100644 --- a/src/format/strsym.c +++ b/src/format/strsym.c @@ -315,7 +315,9 @@ GBinSymbol *g_string_symbol_new_dynamic(const char *string, const vmpa2t *addr, static void g_string_symbol_check_encoding(GStrSymbol *symbol) { + size_t length; /* Taille de la chaîne */ const char *string; /* Données à analyser */ + size_t i; /* Boucle de parcours */ switch (symbol->encoding) { @@ -325,25 +327,47 @@ static void g_string_symbol_check_encoding(GStrSymbol *symbol) case SET_UTF_8: case SET_MUTF_8: - string = g_string_symbol_get_utf8(symbol); + string = g_string_symbol_get_utf8(symbol, &length); - if (!g_utf8_validate(string, -1, NULL)) + if (!g_utf8_validate(string, length, NULL)) symbol->encoding = SET_ASCII; break; case SET_GUESS: - string = g_string_symbol_get_utf8(symbol); + string = g_string_symbol_get_utf8(symbol, &length); - if (g_str_is_ascii(string)) - symbol->encoding = SET_ASCII; + /** + * Afin de ne pas réaliser d'allocation avec strndup(), on simule + * un appel à g_str_is_ascii() : + * + * gboolean g_str_is_ascii (const gchar *str); + * + * """ + * Determines if a string is pure ASCII. A string is pure ASCII + * if it contains no bytes with the high bit set. + * """" + */ - else if (g_utf8_validate(string, -1, NULL)) - symbol->encoding = SET_UTF_8; + symbol->encoding = SET_ASCII; - else - symbol->encoding = SET_ASCII; + for (i = 0; i < length; i++) + if (string[i] & 0x80) + { + symbol->encoding = SET_GUESS; + break; + } + + if (symbol->encoding == SET_GUESS) + { + if (g_utf8_validate(string, -1, NULL)) + symbol->encoding = SET_UTF_8; + + else + symbol->encoding = SET_ASCII; + + } break; @@ -385,16 +409,17 @@ StringEncodingType g_string_symbol_get_encoding(const GStrSymbol *symbol) * * * Retour : Chaîne de caractères d'origine. * * * -* Remarques : - * +* Remarques : Cf. fonction g_string_symbol_get_utf8() pour l'existence * +* du paramètre length. * * * ******************************************************************************/ -const char *g_string_symbol_get_raw(const GStrSymbol *symbol) +const char *g_string_symbol_get_raw(const GStrSymbol *symbol, size_t *length) { const char *result; /* Données à retourner */ const mrange_t *range; /* Couverture du symbole */ vmpa2t pos; /* Tête de lecture modifiable */ - phys_t length; /* Taille de la chaîne */ + phys_t len; /* Taille de la chaîne */ if (symbol->has_content) { @@ -402,14 +427,19 @@ const char *g_string_symbol_get_raw(const GStrSymbol *symbol) copy_vmpa(&pos, get_mrange_addr(range)); - length = get_mrange_length(range); + len = get_mrange_length(range); + + result = (const char *)g_binary_content_get_raw_access(symbol->content, &pos, len); - result = (const char *)g_binary_content_get_raw_access(symbol->content, &pos, length); + *length = len; } else + { result = symbol->string; + *length = strlen(result); + } return result; @@ -419,21 +449,29 @@ const char *g_string_symbol_get_raw(const GStrSymbol *symbol) /****************************************************************************** * * * Paramètres : symbol = symbole à venir consulter. * +* length = taille de la chaîne renvoyée. [OUT] * * * * Description : Fournit la chaîne de caractères du symbole. * * * * Retour : Chaîne de caractères, à priori en UTF-8. * * * -* Remarques : - * +* Remarques : Lorsque la chaîne est lue à partir du contenu brut, elle * +* peut ne pas être terminée par un octet nul (c'est le cas * +* avec le fichier strings.asm par exemple, dans la suite de * +* tests, où la séparation est marquée par un simple retour * +* chariot). * +* * +* Un appel à strlen() sur le résultat renvoyé n'est donc pas * +* fiable à posteriori, donc on renseigne la taille ici. * * * ******************************************************************************/ -const char *g_string_symbol_get_utf8(const GStrSymbol *symbol) +const char *g_string_symbol_get_utf8(const GStrSymbol *symbol, size_t *length) { const char *result; /* Données à retourner */ const mrange_t *range; /* Couverture du symbole */ vmpa2t pos; /* Tête de lecture modifiable */ - phys_t length; /* Taille de la chaîne */ + phys_t len; /* Taille de la chaîne */ if (symbol->has_content) { @@ -441,14 +479,19 @@ const char *g_string_symbol_get_utf8(const GStrSymbol *symbol) copy_vmpa(&pos, get_mrange_addr(range)); - length = get_mrange_length(range); + len = get_mrange_length(range); - result = (const char *)g_binary_content_get_raw_access(symbol->content, &pos, length); + result = (const char *)g_binary_content_get_raw_access(symbol->content, &pos, len); + + *length = len; } else + { result = symbol->string; + *length = strlen(result); + } return result; @@ -489,13 +532,11 @@ bool g_string_symbol_build_label(GStrSymbol *symbol, GBinFormat *format) /* Base de décision */ - base = g_string_symbol_get_utf8(symbol); + base = g_string_symbol_get_utf8(symbol, &length); if (base == NULL) return false; - length = strlen(base); - /* Phase de constitution */ allocated = length + 5 + VMPA_MAX_LEN + 1; @@ -691,12 +732,10 @@ void g_string_symbol_print(const GStrSymbol *symbol, GBufferLine *line) const char *string; /* Chaîne de caractères */ size_t len; /* Taille du texte à créer */ - string = g_string_symbol_get_utf8(symbol); + string = g_string_symbol_get_utf8(symbol, &len); g_buffer_line_append_text(line, BLC_ASSEMBLY, "\"", 1, RTT_STRING, NULL); - len = strlen(string); - if (len > 0) g_buffer_line_append_text(line, BLC_ASSEMBLY, string, len, RTT_STRING, NULL); diff --git a/src/format/strsym.h b/src/format/strsym.h index b074a28..4a1404b 100644 --- a/src/format/strsym.h +++ b/src/format/strsym.h @@ -76,10 +76,10 @@ GBinSymbol *g_string_symbol_new_dynamic(const char *, const vmpa2t *, StringEnco StringEncodingType g_string_symbol_get_encoding(const GStrSymbol *); /* Fournit la chaîne brute de caractères du symbole. */ -const char *g_string_symbol_get_raw(const GStrSymbol *); +const char *g_string_symbol_get_raw(const GStrSymbol *, size_t *); /* Fournit la chaîne de caractères du symbole. */ -const char *g_string_symbol_get_utf8(const GStrSymbol *); +const char *g_string_symbol_get_utf8(const GStrSymbol *, size_t *); /* Construit une désignation pour chaîne de caractères. */ bool g_string_symbol_build_label(GStrSymbol *, GBinFormat *); diff --git a/src/gui/panels/strings.c b/src/gui/panels/strings.c index 5bba0ca..8814c0b 100644 --- a/src/gui/panels/strings.c +++ b/src/gui/panels/strings.c @@ -745,7 +745,9 @@ static void reload_strings_for_new_list_view(const GStringsPanel *panel, GtkStat VMPA_BUFFER(virt); /* Adresse virtuelle */ GBinPortion *portion; /* Zone mémoire d'appartenance */ const char *area; /* Description de la zone */ + size_t len; /* Taille de la chaîne */ const char *text; /* Texte original référencé */ + char *real_text; /* Texte avec octet nul final */ GtkTreeIter iter; /* Point d'insertion */ builder = G_PANEL_ITEM(panel)->builder; @@ -779,9 +781,11 @@ static void reload_strings_for_new_list_view(const GStringsPanel *panel, GtkStat area = g_binary_portion_get_desc(portion); g_object_unref(G_OBJECT(portion)); - text = g_string_symbol_get_utf8(G_STR_SYMBOL(symbol)); + text = g_string_symbol_get_utf8(G_STR_SYMBOL(symbol), &len); if (text == NULL) goto rsfnlv_next; + real_text = strndup(text, len); + gtk_list_store_append(store, &iter); gtk_list_store_set(store, &iter, STC_SYMBOL, symbol, @@ -790,10 +794,12 @@ static void reload_strings_for_new_list_view(const GStringsPanel *panel, GtkStat STC_AREA, area, STC_NAME, NULL, STC_VALUE, NULL, - STC_ORIGINAL, text, + STC_ORIGINAL, real_text, STC_MATCHED, false, -1); + free(real_text); + update_string_node(data, store, &iter); data->count++; -- cgit v0.11.2-87-g4458