From a5758a42acdfaf0ac20c4cfb9cf162a9b4440e39 Mon Sep 17 00:00:00 2001
From: Cyrille Bagard <nocbos@gmail.com>
Date: Sat, 23 Apr 2016 23:38:02 +0200
Subject: Limited the length of displayed SHA1 binary value for Dex files.

---
 ChangeLog                  | 14 ++++++++++++
 plugins/readdex/header.c   |  1 +
 src/arch/instruction-int.h |  4 ++--
 src/arch/instruction.c     | 43 +++++++++++++++++++++++++++++++++--
 src/arch/instruction.h     |  6 +++++
 src/glibext/gbufferline.c  | 56 +++++++++++++++++++++++++---------------------
 src/glibext/gbufferline.h  |  2 +-
 7 files changed, 96 insertions(+), 30 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index cfc9c84..2cc6b1f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,19 @@
 16-04-23  Cyrille Bagard <nocbos@gmail.com>
 
+	* plugins/readdex/header.c:
+	Limit the length of displayed SHA1 binary value for Dex files.
+
+	* src/arch/instruction-int.h:
+	* src/arch/instruction.c:
+	* src/arch/instruction.h:
+	Store a largest displayed size of binary code for instructions.
+
+	* src/glibext/gbufferline.c:
+	* src/glibext/gbufferline.h:
+	Truncate binary code when requested.
+
+16-04-23  Cyrille Bagard <nocbos@gmail.com>
+
 	* src/format/dex/class.c:
 	Register all loaded class methods as symbols.
 
diff --git a/plugins/readdex/header.c b/plugins/readdex/header.c
index 999baa4..5089f96 100644
--- a/plugins/readdex/header.c
+++ b/plugins/readdex/header.c
@@ -98,6 +98,7 @@ bool annotate_dex_header(GDexFormat *format)
     copy_vmpa(&start, &pos);
     instr = g_raw_instruction_new_array(content, MDS_32_BITS, 5, &pos, endian);
 
+    g_arch_instruction_set_displayed_max_length(instr, 4);
     SET_IMM_DISPLAY(instr, operand, 0, IOD_HEX);
 
     ADD_RAW_AS_SYM(format, symbol, &start, instr, comment, _("SHA-1 signature used to uniquely identify files"));
diff --git a/src/arch/instruction-int.h b/src/arch/instruction-int.h
index 69cdc8a..f9f548b 100644
--- a/src/arch/instruction-int.h
+++ b/src/arch/instruction-int.h
@@ -60,6 +60,8 @@ struct _GArchInstruction
     const char *suffix;                     /* Complément au nom affiché   */
     char *cached_keyword;                   /* Désignation complète        */
 
+    phys_t max_displayed_len;               /* Quantité de code affichée   */
+
     ArchInstrFlag flags;                    /* Informations complémentaires*/
     instr_hook_fc hooks[IPH_COUNT];         /* Traitements complémentaires */
 
@@ -100,8 +102,6 @@ struct _GArchInstruction
     //is_instruction_return_fc is_return;     /* Retour de fonction ou pas ? */
     decomp_instr_fc decomp;                 /* Procédure de décompilation  */
 
-    bool is_return;                         /* Retour de fonction ou pas ? */   // FIXME : à virer
-
 };
 
 
diff --git a/src/arch/instruction.c b/src/arch/instruction.c
index 4de70b7..c2e4c7c 100644
--- a/src/arch/instruction.c
+++ b/src/arch/instruction.c
@@ -105,7 +105,7 @@ static void g_arch_instruction_init(GArchInstruction *instr)
 {
     DL_LIST_ITEM_INIT(&instr->flow);
 
-    instr->is_return = false;
+    instr->max_displayed_len = VMPA_NO_PHYSICAL;
 
     g_rw_lock_init(&instr->from_access);
     g_atomic_int_set(&instr->hold_from_access, 0);
@@ -972,6 +972,45 @@ const char *g_arch_instruction_get_keyword(const GArchInstruction *instr, AsmSyn
 
 /******************************************************************************
 *                                                                             *
+*  Paramètres  : instr = instruction d'assemblage à consulter.                *
+*                                                                             *
+*  Description : Indique si elle existe la quantité maximale de code affiché. *
+*                                                                             *
+*  Retour      : Quantité de code affichée au plus ou VMPA_NO_PHYSICAL.       *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+phys_t g_arch_instruction_get_displayed_max_length(const GArchInstruction *instr)
+{
+    return instr->max_displayed_len;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
+*  Paramètres  : instr = instruction d'assemblage à consulter.                *
+*                max   = quantité affichée au plus ou VMPA_NO_PHYSICAL.       *
+*                                                                             *
+*  Description : Définit la quantité maximale de code affiché.                *
+*                                                                             *
+*  Retour      : -                                                            *
+*                                                                             *
+*  Remarques   : -                                                            *
+*                                                                             *
+******************************************************************************/
+
+void g_arch_instruction_set_displayed_max_length(GArchInstruction *instr, phys_t max)
+{
+    instr->max_displayed_len = max;
+
+}
+
+
+/******************************************************************************
+*                                                                             *
 *  Paramètres  : instr   = instruction d'assemblage à représenter.            *
 *                buffer  = espace où placer ledit contenu.                    *
 *                msize   = taille idéale des positions et adresses;           *
@@ -997,7 +1036,7 @@ static GBufferLine *_g_arch_instruction_print(const GArchInstruction *instr, GCo
 
     g_buffer_line_add_flag(result, BLF_HAS_CODE);
 
-    g_buffer_line_fill_for_instr(result, msize/* TODO ! */, msize, content, true);
+    g_buffer_line_fill_for_instr(result, msize/* TODO ! */, msize, content, instr->max_displayed_len);
 
     /* Instruction proprement dite */
 
diff --git a/src/arch/instruction.h b/src/arch/instruction.h
index f26a240..3d261a9 100644
--- a/src/arch/instruction.h
+++ b/src/arch/instruction.h
@@ -233,6 +233,12 @@ size_t g_arch_instruction_compute_group_index(GArchInstruction **, GArchInstruct
 /* Fournit le nom humain de l'instruction manipulée. */
 const char *g_arch_instruction_get_keyword(const GArchInstruction *, AsmSyntax);
 
+/* Indique si elle existe la quantité maximale de code affiché. */
+phys_t g_arch_instruction_get_displayed_max_length(const GArchInstruction *);
+
+/* Définit la quantité maximale de code affiché. */
+void g_arch_instruction_set_displayed_max_length(GArchInstruction *, phys_t);
+
 /* Ajoute à un tampon GLib le contenu de l'instance spécifiée. */
 GBufferLine *g_arch_instruction_print(const GArchInstruction *, GCodeBuffer *, MemoryDataSize, const GBinContent *, AsmSyntax);
 
diff --git a/src/glibext/gbufferline.c b/src/glibext/gbufferline.c
index f47442d..65e73d0 100644
--- a/src/glibext/gbufferline.c
+++ b/src/glibext/gbufferline.c
@@ -814,7 +814,7 @@ void g_buffer_line_fill_mrange(GBufferLine *line, MemoryDataSize psize, MemoryDa
 *                psize   = taille souhaitée de l'impression des positions.    *
 *                vsize   = taille souhaitée de l'impression des adresses.     *
 *                content = contenu binaire global à venir lire.               *
-*                full    = la portion est assez courte pour être entière ?    *
+*                max     = taille maximal de la portion binaire en octets.    *
 *                                                                             *
 *  Description : Construit le tronc commun d'une ligne d'instruction.         *
 *                                                                             *
@@ -824,9 +824,10 @@ void g_buffer_line_fill_mrange(GBufferLine *line, MemoryDataSize psize, MemoryDa
 *                                                                             *
 ******************************************************************************/
 
-void g_buffer_line_fill_for_instr(GBufferLine *line, MemoryDataSize psize, MemoryDataSize vsize, const GBinContent *content, bool full)
+void g_buffer_line_fill_for_instr(GBufferLine *line, MemoryDataSize psize, MemoryDataSize vsize, const GBinContent *content, phys_t max)
 {
     phys_t length;                          /* Taille de la couverture     */
+    bool truncated;                         /* Indique si le code est coupé*/
     size_t required;                        /* Taille de traitement requise*/ 
     char static_buffer[64];                 /* Petit tampon local rapide   */
     char *bin_code;                         /* Tampon utilisé pour le code */
@@ -846,7 +847,15 @@ void g_buffer_line_fill_for_instr(GBufferLine *line, MemoryDataSize psize, Memor
 
     length = get_mrange_length(&line->range);
 
-    required = length * 3 + 3;
+    truncated = (max != VMPA_NO_PHYSICAL && length > max);
+
+    if (truncated)
+    {
+        length = max;
+        required = length * 3 + 4 /* "..." */ + 1;
+    }
+    else
+        required = length * 3 + 1;
 
     if (required <= sizeof(static_buffer))
         bin_code = static_buffer;
@@ -859,40 +868,37 @@ void g_buffer_line_fill_for_instr(GBufferLine *line, MemoryDataSize psize, Memor
 
     for (i = 0, iter = bin_code; i < length; i++, iter += ret)
     {
-        if (!g_binary_content_read_u8(content, &pos, &byte))
-        {
-            iter[0] = '?';
-            iter[1] = '?';
-        }
+        if (i == 0)
+            ret = 0;
         else
         {
-            iter[0] = charset[byte >> 4];
-            iter[1] = charset[byte & 0x0f];
+            iter[0] = ' ';
+            ret = 1;
         }
 
-        if ((i + 1) < length)
+        if (!g_binary_content_read_u8(content, &pos, &byte))
         {
-            iter[2] = ' ';
-            ret = 3;
+            iter[ret + 0] = '?';
+            iter[ret + 1] = '?';
         }
-
         else
         {
-            if (full)
-            {
-                iter[2] = '\0';
-                ret = 2;
-            }
-            else
-            {
-                strcpy(iter + 2, "...");
-                ret = 5;
-            }
-
+            iter[ret + 0] = charset[byte >> 4];
+            iter[ret + 1] = charset[byte & 0x0f];
         }
 
+        ret += 2;
+
     }
 
+    if (truncated)
+    {
+        strcpy(iter, "...");
+        iter += 3;
+    }
+    else
+        *iter = '\0';
+
     /* Conclusion */
 
     g_buffer_line_insert_text(line, BLC_BINARY, bin_code, iter - bin_code, RTT_RAW_CODE);
diff --git a/src/glibext/gbufferline.h b/src/glibext/gbufferline.h
index 89313be..e4c2da5 100644
--- a/src/glibext/gbufferline.h
+++ b/src/glibext/gbufferline.h
@@ -112,7 +112,7 @@ const mrange_t *g_buffer_line_get_range(const GBufferLine *);
 void g_buffer_line_fill_mrange(GBufferLine *, MemoryDataSize, MemoryDataSize);
 
 /* Construit le tronc commun d'une ligne d'instruction. */
-void g_buffer_line_fill_for_instr(GBufferLine *, MemoryDataSize, MemoryDataSize, const GBinContent *, bool);
+void g_buffer_line_fill_for_instr(GBufferLine *, MemoryDataSize, MemoryDataSize, const GBinContent *, phys_t);
 
 /* Donne le segment présent à une abscisse donnée. */
 GBufferSegment *g_buffer_line_get_segment_at(const GBufferLine *, const gint [BLC_COUNT], const bool *, gint *, gint *, GdkScrollDirection, bool);
-- 
cgit v0.11.2-87-g4458