summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCyrille Bagard <nocbos@gmail.com>2019-01-04 18:59:14 (GMT)
committerCyrille Bagard <nocbos@gmail.com>2019-01-04 18:59:14 (GMT)
commite827eb8bdc797d2a8c194e675bd300e97aee6166 (patch)
treeaee7f9186f9e20eab24c20dd2cd0ba01d4f874e2
parentb9fe3a839e9212b809d64c11bf92b703adb18fb2 (diff)
Handled non null-terminated strings
-rw-r--r--plugins/pychrysalide/format/strsym.c10
-rw-r--r--src/format/strsym.c89
-rw-r--r--src/format/strsym.h4
-rw-r--r--src/gui/panels/strings.c10
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++;