]> git.feebdaed.xyz Git - 0xmirror/radare2.git/commitdiff
Cleanup the pdb parser, adding more boundary checks and reuse r2 primitives master
authorpancake <pancake@nowsecure.com>
Fri, 26 Dec 2025 23:46:57 +0000 (00:46 +0100)
committerGitHub <noreply@github.com>
Fri, 26 Dec 2025 23:46:57 +0000 (00:46 +0100)
* Fixes two oobread bugs (15478891547971)

13 files changed:
libr/bin/format/pdb/dbi.c
libr/bin/format/pdb/fpo.c
libr/bin/format/pdb/gdata.inc.c
libr/bin/format/pdb/omap.c
libr/bin/format/pdb/pdb.c
libr/bin/format/pdb/pdb_downloader.c
libr/bin/format/pdb/stream_file.c
libr/bin/format/pdb/stream_file.h
libr/bin/format/pdb/stream_pe.c
libr/bin/format/pdb/tpi.c
libr/bin/format/pdb/tpi.h
libr/bin/format/pdb/types.h
libr/util/hex.c

index 041e7a3fd68ee7d2afbbbd63b43ed8b6eb22fa6b..884e23955626a6e5e62ba519f612c5f8381f7284 100644 (file)
@@ -8,8 +8,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 static void free_dbi_stream(STpiStream *ss, void *stream) {
        SDbiStream *t = (SDbiStream *)stream;
-       SDBIExHeader *dbi_ex_header = 0;
-
+       SDBIExHeader *dbi_ex_header = NULL;
        RListIter *it = r_list_iterator (t->dbiexhdrs);
        while (r_list_iter_next (it)) {
                dbi_ex_header = (SDBIExHeader *)r_list_iter_get (it);
@@ -44,52 +43,49 @@ static void parse_dbi_header(SDBIHeader *dbi_header, R_STREAM_FILE *stream_file)
        stream_file_read (stream_file, sizeof (ut32), (char *)&dbi_header->resvd);
 }
 
-///////////////////////////////////////////////////////////////////////////////
-static int parse_ssymbol_range(char *data, int max_len, SSymbolRange *symbol_range) {
-       int read_bytes = 0;
-
-       READ2 (read_bytes, max_len, symbol_range->section, data, st16);
-       READ2 (read_bytes, max_len, symbol_range->padding1, data, st16);
-       READ4 (read_bytes, max_len, symbol_range->offset, data, st32);
-       READ4 (read_bytes, max_len, symbol_range->size, data, st32);
-       READ4 (read_bytes, max_len, symbol_range->flags, data, ut32);
-       READ4 (read_bytes, max_len, symbol_range->module, data, st32);
-
-       // TODO: why not need to read this padding?
-       //      READ2 (read_bytes, max_len, symbol_range->padding2, data, short);
-       READ4 (read_bytes, max_len, symbol_range->data_crc, data, ut32);
-       READ4 (read_bytes, max_len, symbol_range->reloc_crc, data, ut32);
-
-       return read_bytes;
+static int parse_ssymbol_range(const ut8 *data, ut32 max_len, SSymbolRange *symbol_range) {
+       const ut32 size = 28;
+       if (!can_read (0, size, max_len)) {
+               return 0;
+       }
+       symbol_range->section = r_read_le16 (data);
+       symbol_range->padding1 = r_read_le16 (data + 2);
+       symbol_range->offset = (st32)r_read_le32 (data + 4);
+       symbol_range->size = (st32)r_read_le32 (data + 8);
+       symbol_range->flags = r_read_le32 (data + 12);
+       symbol_range->module = (st32)r_read_le32 (data + 16);
+       symbol_range->data_crc = r_read_le32 (data + 20);
+       symbol_range->reloc_crc = r_read_le32 (data + 24);
+       return size;
 }
 
-///////////////////////////////////////////////////////////////////////////////
-static int parse_dbi_ex_header(char *data, int max_len, SDBIExHeader *dbi_ex_header) {
-       ut32 read_bytes = 0, before_read_bytes = 0;
-
-       READ4 (read_bytes, max_len, dbi_ex_header->opened, data, ut32);
-
-       before_read_bytes = read_bytes;
-       read_bytes += parse_ssymbol_range (data, max_len, &dbi_ex_header->range);
-       data += (read_bytes - before_read_bytes);
-
-       READ2 (read_bytes, max_len, dbi_ex_header->flags, data, ut16);
-       READ2 (read_bytes, max_len, dbi_ex_header->stream, data, st16);
-       READ4 (read_bytes, max_len, dbi_ex_header->symSize, data, ut32);
-       READ4 (read_bytes, max_len, dbi_ex_header->oldLineSize, data, ut32);
-       READ4 (read_bytes, max_len, dbi_ex_header->lineSize, data, ut32);
-       READ2 (read_bytes, max_len, dbi_ex_header->nSrcFiles, data, st16);
-       READ2 (read_bytes, max_len, dbi_ex_header->padding1, data, st16);
-       READ4 (read_bytes, max_len, dbi_ex_header->offsets, data, ut32);
-       READ4 (read_bytes, max_len, dbi_ex_header->niSource, data, ut32);
-       READ4 (read_bytes, max_len, dbi_ex_header->niCompiler, data, ut32);
-
-       before_read_bytes = read_bytes;
-       parse_sctring (&dbi_ex_header->modName, (unsigned char *)data, &read_bytes, max_len);
-       data += (read_bytes - before_read_bytes);
-
-       parse_sctring (&dbi_ex_header->objName, (unsigned char *)data, &read_bytes, max_len);
-
+static int parse_dbi_ex_header(ut8 *data, ut32 max_len, SDBIExHeader *dbi_ex_header) {
+       const ut32 fixed_size = 64;
+       if (!can_read (0, fixed_size, max_len)) {
+               return 0;
+       }
+       dbi_ex_header->opened = r_read_le32 (data);
+       const int range_sz = parse_ssymbol_range (data + 4, max_len - 4, &dbi_ex_header->range);
+       if (range_sz == 0) {
+               return 0;
+       }
+       const ut8 *p = data + 4 + range_sz;
+       dbi_ex_header->flags = r_read_le16 (p);
+       dbi_ex_header->stream = (st16)r_read_le16 (p + 2);
+       dbi_ex_header->symSize = r_read_le32 (p + 4);
+       dbi_ex_header->oldLineSize = r_read_le32 (p + 8);
+       dbi_ex_header->lineSize = r_read_le32 (p + 12);
+       dbi_ex_header->nSrcFiles = (st16)r_read_le16 (p + 16);
+       dbi_ex_header->padding1 = (st16)r_read_le16 (p + 18);
+       dbi_ex_header->offsets = r_read_le32 (p + 20);
+       dbi_ex_header->niSource = r_read_le32 (p + 24);
+       dbi_ex_header->niCompiler = r_read_le32 (p + 28);
+       ut32 read_bytes = fixed_size;
+       ut8 *str_data = data + fixed_size;
+       ut32 before = read_bytes;
+       parse_sctring (&dbi_ex_header->modName, str_data, &read_bytes, max_len);
+       str_data += (read_bytes - before);
+       parse_sctring (&dbi_ex_header->objName, str_data, &read_bytes, max_len);
        return read_bytes;
 }
 
@@ -116,9 +112,9 @@ void init_dbi_stream(SDbiStream *dbi_stream) {
 ///////////////////////////////////////////////////////////////////////////////
 void parse_dbi_stream(void *parsed_pdb_stream, R_STREAM_FILE *stream_file) {
        SDbiStream *dbi_stream = (SDbiStream *)parsed_pdb_stream;
-       SDBIExHeader *dbi_ex_header = 0;
+       SDBIExHeader *dbi_ex_header = NULL;
        int pos = 0;
-       char *dbiexhdr_data = 0, *p_tmp = 0;
+       ut8 *dbiexhdr_data = NULL, *p_tmp = NULL;
        int size = 0, sz = 0;
        int i = 0;
 
@@ -128,11 +124,11 @@ void parse_dbi_stream(void *parsed_pdb_stream, R_STREAM_FILE *stream_file) {
        stream_file_seek (stream_file, pos, 0);
 
        size = dbi_stream->dbi_header.module_size;
-       dbiexhdr_data = (char *)malloc (size);
+       dbiexhdr_data = malloc (size);
        if (!dbiexhdr_data) {
                return;
        }
-       stream_file_read (stream_file, size, dbiexhdr_data);
+       stream_file_read (stream_file, size, (char *)dbiexhdr_data);
 
        dbi_stream->dbiexhdrs = r_list_new ();
        p_tmp = dbiexhdr_data;
index e0de2726d53625466094bb0f083e811523486083..f96ac302e9e110932935503750946a16df9d8e1a 100644 (file)
@@ -1,62 +1,58 @@
+/* radare - LGPL - Copyright 2014-2025 - inisider, pancake */
+
 #include "types.h"
 #include "fpo.h"
 #include "stream_file.h"
 
-///////////////////////////////////////////////////////////////////////////////
-static int parse_fpo_data(char *data, int data_size, int *read_bytes, SFPO_DATA *fpo_data) {
-       int curr_read_bytes = *read_bytes;
-
-       READ4 (*read_bytes, data_size, fpo_data->ul_off_start, data, ut32);
-       READ4 (*read_bytes, data_size, fpo_data->cb_proc_size, data, ut32);
-       READ4 (*read_bytes, data_size, fpo_data->cdw_locals, data, ut32);
-       READ2 (*read_bytes, data_size, fpo_data->cdw_params, data, ut16);
-       READ2 (*read_bytes, data_size, fpo_data->bit_values.bit_values, data, ut16);
-
-       fpo_data->bit_values.bit_values = SWAP_UINT16 (fpo_data->bit_values.bit_values);
-
-       return (*read_bytes - curr_read_bytes);
+static int parse_fpo_data(const ut8 *data, ut32 data_size, ut32 pos, SFPO_DATA *fpo_data) {
+       const ut32 size = 16;
+       if (!can_read (pos, size, data_size)) {
+               return 0;
+       }
+       fpo_data->ul_off_start = r_read_le32 (data);
+       fpo_data->cb_proc_size = r_read_le32 (data + 4);
+       fpo_data->cdw_locals = r_read_le32 (data + 8);
+       fpo_data->cdw_params = r_read_le16 (data + 12);
+       fpo_data->bit_values.bit_values = r_read_be16 (data + 14);
+       return size;
 }
 
-///////////////////////////////////////////////////////////////////////////////
-static int parse_fpo_data_v2(char *data, int data_size, int *read_bytes, SFPO_DATA_V2 *fpo_data) {
-       int curr_read_bytes = *read_bytes;
-       memcpy (fpo_data, data, sizeof (SFPO_DATA_V2));
-       *read_bytes += sizeof (SFPO_DATA_V2);
-       return (*read_bytes - curr_read_bytes);
+static int parse_fpo_data_v2(const ut8 *data, ut32 data_size, ut32 pos, SFPO_DATA_V2 *fpo_data) {
+       const ut32 size = sizeof (SFPO_DATA_V2);
+       if (!can_read (pos, size, data_size)) {
+               return 0;
+       }
+       memcpy (fpo_data, data, size);
+       return size;
 }
 
-///////////////////////////////////////////////////////////////////////////////
 void parse_fpo_stream(STpiStream *ss, void *stream, R_STREAM_FILE *stream_file) {
-       int data_size;
-       char *data = 0, *ptmp = 0;
-       int curr_read_bytes = 0, read_bytes = 0;
-       SFPO_DATA *fpo_data = 0;
-       SFPOStream *fpo_stream = 0;
-
-       stream_file_get_size (stream_file, &data_size);
-       data = (char *)malloc (data_size);
-       stream_file_get_data (stream_file, data);
+       int data_size = stream_file_get_size (stream_file);
+       if (data_size < 1) {
+               return;
+       }
+       ut8 *data = malloc (data_size);
+       if (!data) {
+               return;
+       }
+       stream_file_get_data (stream_file, (char *)data);
 
-       fpo_stream = (SFPOStream *)stream;
+       SFPOStream *fpo_stream = (SFPOStream *)stream;
        fpo_stream->fpo_data_list = r_list_new ();
-       ptmp = data;
-       while (read_bytes < data_size) {
-               fpo_data = (SFPO_DATA *)malloc (sizeof (SFPO_DATA));
-               curr_read_bytes = parse_fpo_data (ptmp, data_size, &read_bytes, fpo_data);
-               ptmp += curr_read_bytes;
-
-               if (!curr_read_bytes) {
+       ut32 pos = 0;
+       while (pos < (ut32)data_size) {
+               SFPO_DATA *fpo_data = R_NEW0 (SFPO_DATA);
+               const int sz = parse_fpo_data (data + pos, data_size, pos, fpo_data);
+               if (!sz) {
                        free (fpo_data);
                        break;
                }
-
                r_list_append (fpo_stream->fpo_data_list, fpo_data);
+               pos += sz;
        }
-
        free (data);
 }
 
-///////////////////////////////////////////////////////////////////////////////
 void free_fpo_stream(STpiStream *ss, void *stream) {
        SFPOStream *fpo_stream = (SFPOStream *)stream;
        RListIter *it = 0;
@@ -70,7 +66,6 @@ void free_fpo_stream(STpiStream *ss, void *stream) {
        r_list_free (fpo_stream->fpo_data_list);
 }
 
-///////////////////////////////////////////////////////////////////////////////
 void free_fpo_new_stream(STpiStream *ss, void *stream) {
        SFPONewStream *fpo_stream = (SFPONewStream *)stream;
        RListIter *it = 0;
@@ -84,40 +79,32 @@ void free_fpo_new_stream(STpiStream *ss, void *stream) {
        r_list_free (fpo_stream->fpo_data_list);
 }
 
-///////////////////////////////////////////////////////////////////////////////
 void parse_fpo_new_stream(STpiStream *ss, void *stream, R_STREAM_FILE *stream_file) {
-       int data_size;
-       char *data = 0, *ptmp = 0;
-       int curr_read_bytes = 0, read_bytes = 0;
-       SFPO_DATA_V2 *fpo_data = 0;
-       SFPONewStream *fpo_stream = 0;
-
-       stream_file_get_size (stream_file, &data_size);
-       data = (char *)malloc (data_size);
+       int data_size = stream_file_get_size (stream_file);
+       if (data_size < 1) {
+               return;
+       }
+       ut8 *data = malloc (data_size);
        if (!data) {
                return;
        }
-       stream_file_get_data (stream_file, data);
+       stream_file_get_data (stream_file, (char *)data);
 
-       fpo_stream = (SFPONewStream *)stream;
+       SFPONewStream *fpo_stream = (SFPONewStream *)stream;
        fpo_stream->fpo_data_list = r_list_new ();
-       ptmp = data;
-       while (read_bytes < data_size) {
-               fpo_data = (SFPO_DATA_V2 *)malloc (sizeof (SFPO_DATA_V2));
+       ut32 pos = 0;
+       while (pos < (ut32)data_size) {
+               SFPO_DATA_V2 *fpo_data = malloc (sizeof (SFPO_DATA_V2));
                if (!fpo_data) {
-                       free (data);
-                       return;
+                       break;
                }
-               curr_read_bytes = parse_fpo_data_v2 (ptmp, data_size, &read_bytes, fpo_data);
-               ptmp += curr_read_bytes;
-
-               if (!curr_read_bytes) {
+               const int sz = parse_fpo_data_v2 (data + pos, data_size, pos, fpo_data);
+               if (!sz) {
                        free (fpo_data);
                        break;
                }
-
                r_list_append (fpo_stream->fpo_data_list, fpo_data);
+               pos += sz;
        }
-
        free (data);
 }
index 0cf4fa5fc3d4914ab2228cb41ffb3ad4e9870e4e..ce9e781485c82a9d835c5f82af75543b270fd81a 100644 (file)
@@ -3,26 +3,31 @@
 #include "tpi.h"
 
 ///////////////////////////////////////////////////////////////////////////////
-static int parse_global(char *data, int data_size, SGlobal *global) {
-       unsigned int read_bytes = 2;
-
-       READ4 (read_bytes, data_size, global->symtype, data, ut32);
-       READ4 (read_bytes, data_size, global->offset, data, ut32);
-       READ2 (read_bytes, data_size, global->segment, data, ut8);
+static int parse_global(const ut8 *data, ut32 data_size, SGlobal *global) {
+       const ut32 fixed_size = 10;
+       if (!can_read (0, fixed_size, data_size)) {
+               return 0;
+       }
+       global->symtype = r_read_le32 (data);
+       global->offset = r_read_le32 (data + 4);
+       global->segment = r_read_le16 (data + 8);
+       ut32 read_bytes = fixed_size;
        if (global->leaf_type == 0x110E) {
-               parse_sctring (&global->name, (unsigned char *)data, &read_bytes, data_size);
+               parse_sctring (&global->name, (ut8 *) (data + fixed_size), &read_bytes, data_size);
        } else {
-               READ1 (read_bytes, data_size, global->name.size, data, ut8);
-               init_scstring (&global->name, global->name.size, data);
+               if (!can_read (read_bytes, 1, data_size)) {
+                       return 0;
+               }
+               global->name.size = data[read_bytes];
+               read_bytes++;
+               init_scstring (&global->name, global->name.size, (char *) (data + read_bytes));
        }
-
        return read_bytes;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 static void parse_gdata_stream(STpiStream *ss, void *stream, R_STREAM_FILE *stream_file) {
-       unsigned short len = 0;
-       unsigned short leaf_type = 0;
+       ut16 len = 0;
        SGDATAStream *data_stream = (SGDATAStream *)stream;
 
        data_stream->globals_list = r_list_new ();
@@ -31,17 +36,21 @@ static void parse_gdata_stream(STpiStream *ss, void *stream, R_STREAM_FILE *stre
                if (len == 0) {
                        break;
                }
-               char *data = (char *)malloc (len);
+               ut8 *data = malloc (len);
                if (!data) {
                        return;
                }
-               stream_file_read (stream_file, len, data);
+               stream_file_read (stream_file, len, (char *)data);
 
-               leaf_type = *(unsigned short *) (data);
+               const ut16 leaf_type = r_read_le16 (data);
                if ((leaf_type == 0x110E) || (leaf_type == 0x1009)) {
                        SGlobal *global = R_NEW0 (SGlobal);
+                       if (!global) {
+                               free (data);
+                               return;
+                       }
                        global->leaf_type = leaf_type;
-                       parse_global (data + 2, len, global);
+                       parse_global (data + 2, len - 2, global);
                        r_list_append (data_stream->globals_list, global);
                }
                free (data);
index b760773fa27e4af0c66521ee917da842571ed285..b00a0cc12db70f873637c2e57f6d75dee7a61aae 100644 (file)
@@ -1,4 +1,4 @@
-/* radare - LGPL - Copyright 2014-2016 - iniside, pancake */
+/* radare - LGPL - Copyright 2014-2025 - iniside, pancake */
 
 #include "types.h"
 #include "omap.h"
@@ -12,14 +12,16 @@ static int parse_omap_entry(char *data, int data_size, int *read_bytes, SOmapEnt
 }
 
 void parse_omap_stream(STpiStream *ss, void *stream, R_STREAM_FILE *stream_file) {
-       int data_size;
-       char *data = NULL, *ptmp = NULL;
+       char *ptmp = NULL;
        int curr_read_bytes = 0, read_bytes = 0;
        SOmapEntry *omap_entry = 0;
        SOmapStream *omap_stream = 0;
 
-       stream_file_get_size (stream_file, &data_size);
-       data = (char *)malloc (data_size);
+       int data_size = stream_file_get_size (stream_file);
+       if (data_size < 1) {
+               return;
+       }
+       char *data = (char *)malloc (data_size);
        if (!data) {
                return;
        }
index 0fd5df93f47d84444be01fc17539e157053018c2..4b98113aef976a1db4fe9ac2dcbb0b349b4efb31 100644 (file)
@@ -59,8 +59,7 @@ static char *create_type_name_from_offset(ut64 offset) {
 /// size - default value = -1
 /// page_size - default value = 0x1000
 ///////////////////////////////////////////////////////////////////////////////
-static int init_r_pdb_stream(R_PDB_STREAM *pdb_stream, RBuffer *buf /*FILE *fp*/, int *pages,
-       int pages_amount, int index, int size, int page_size) {
+static int init_r_pdb_stream(R_PDB_STREAM *pdb_stream, RBuffer *buf /*FILE *fp*/, int *pages, int pages_amount, int index, int size, int page_size) {
        pdb_stream->buf = buf;
        pdb_stream->pages = pages;
        pdb_stream->indx = index;
@@ -103,8 +102,7 @@ static int count_pages(int length, int page_size) {
 }
 
 ///////////////////////////////////////////////////////////////////////////////
-static int init_pdb7_root_stream(RBinPdb *pdb, int *root_page_list, int pages_amount,
-       EStream indx, int root_size, int page_size) {
+static int init_pdb7_root_stream(RBinPdb *pdb, int *root_page_list, int pages_amount, EStream indx, int root_size, int page_size) {
        R_PDB_STREAM *pdb_stream = 0;
        int tmp_data_max_size = 0;
        char *tmp_data = NULL, *data_end;
@@ -119,13 +117,12 @@ static int init_pdb7_root_stream(RBinPdb *pdb, int *root_page_list, int pages_am
        R_PDB7_ROOT_STREAM *root_stream7;
 
        pdb->root_stream = R_NEW0 (R_PDB7_ROOT_STREAM);
-       init_r_pdb_stream (&pdb->root_stream->pdb_stream, pdb->buf, root_page_list, pages_amount,
-               indx, root_size, page_size);
+       init_r_pdb_stream (&pdb->root_stream->pdb_stream, pdb->buf, root_page_list, pages_amount, indx, root_size, page_size);
 
        root_stream7 = pdb->root_stream;
        pdb_stream = &(root_stream7->pdb_stream);
 
-       stream_file_get_size (&pdb_stream->stream_file, &data_size);
+       data_size = stream_file_get_size (&pdb_stream->stream_file);
        if (data_size < 1) {
                return 0;
        }
@@ -301,20 +298,13 @@ static void add_index(RList *list, int index, int stream_size, EStream stream_ty
 
 ///////////////////////////////////////////////////////////////////////////////
 static void fill_list_for_stream_parsing(RList *l, SDbiStream *dbi_stream) {
-       add_index (l, dbi_stream->dbi_header.symrecStream, sizeof (SGDATAStream),
-               ePDB_STREAM_GSYM, free_gdata_stream, parse_gdata_stream);
-       add_index (l, dbi_stream->dbg_header.sn_section_hdr, sizeof (SPEStream),
-               ePDB_STREAM_SECT_HDR, free_pe_stream, parse_pe_stream);
-       add_index (l, dbi_stream->dbg_header.sn_section_hdr_orig, sizeof (SPEStream),
-               ePDB_STREAM_SECT__HDR_ORIG, free_pe_stream, parse_pe_stream);
-       add_index (l, dbi_stream->dbg_header.sn_omap_to_src, sizeof (SOmapStream),
-               ePDB_STREAM_OMAP_TO_SRC, free_omap_stream, parse_omap_stream);
-       add_index (l, dbi_stream->dbg_header.sn_omap_from_src, sizeof (SOmapStream),
-               ePDB_STREAM_OMAP_FROM_SRC, free_omap_stream, parse_omap_stream);
-       add_index (l, dbi_stream->dbg_header.sn_fpo, sizeof (SFPOStream),
-               ePDB_STREAM_FPO, free_fpo_stream, parse_fpo_stream);
-       add_index (l, dbi_stream->dbg_header.sn_new_fpo, sizeof (SFPONewStream),
-               ePDB_STREAM_FPO_NEW, free_fpo_stream, parse_fpo_new_stream);
+       add_index (l, dbi_stream->dbi_header.symrecStream, sizeof (SGDATAStream), ePDB_STREAM_GSYM, free_gdata_stream, parse_gdata_stream);
+       add_index (l, dbi_stream->dbg_header.sn_section_hdr, sizeof (SPEStream), ePDB_STREAM_SECT_HDR, free_pe_stream, parse_pe_stream);
+       add_index (l, dbi_stream->dbg_header.sn_section_hdr_orig, sizeof (SPEStream), ePDB_STREAM_SECT__HDR_ORIG, free_pe_stream, parse_pe_stream);
+       add_index (l, dbi_stream->dbg_header.sn_omap_to_src, sizeof (SOmapStream), ePDB_STREAM_OMAP_TO_SRC, free_omap_stream, parse_omap_stream);
+       add_index (l, dbi_stream->dbg_header.sn_omap_from_src, sizeof (SOmapStream), ePDB_STREAM_OMAP_FROM_SRC, free_omap_stream, parse_omap_stream);
+       add_index (l, dbi_stream->dbg_header.sn_fpo, sizeof (SFPOStream), ePDB_STREAM_FPO, free_fpo_stream, parse_fpo_stream);
+       add_index (l, dbi_stream->dbg_header.sn_new_fpo, sizeof (SFPONewStream), ePDB_STREAM_FPO_NEW, free_fpo_stream, parse_fpo_new_stream);
 
        // unparsed, but know their names
        add_index (l, dbi_stream->dbg_header.sn_xdata, 0, ePDB_STREAM_XDATA, 0, 0);
@@ -358,10 +348,7 @@ static int pdb_read_root(RBinPdb *pdb) {
                        i++;
                        continue;
                }
-               init_r_stream_file (&stream_file, pdb->buf, (int *)page->stream_pages,
-                       page->num_pages /*root_stream->pdb_stream.pages_amount*/,
-                       page->stream_size,
-                       root_stream->pdb_stream.page_size);
+               init_r_stream_file (&stream_file, pdb->buf, (int *)page->stream_pages, page->num_pages /*root_stream->pdb_stream.pages_amount*/, page->stream_size, root_stream->pdb_stream.page_size);
                switch (i) {
                // TODO: rewrite for style like for streams from dbg stream
                // look default
@@ -398,9 +385,7 @@ static int pdb_read_root(RBinPdb *pdb) {
                        }
 
                        pdb_stream = R_NEW0 (R_PDB_STREAM);
-                       init_r_pdb_stream (pdb_stream, pdb->buf, (int *)page->stream_pages,
-                               root_stream->pdb_stream.pages_amount, i,
-                               page->stream_size, root_stream->pdb_stream.page_size);
+                       init_r_pdb_stream (pdb_stream, pdb->buf, (int *)page->stream_pages, root_stream->pdb_stream.pages_amount, i, page->stream_size, root_stream->pdb_stream.page_size);
                        r_list_append (pList, pdb_stream);
                        break;
                }
@@ -498,8 +483,7 @@ static bool pdb7_parse(RBinPdb *pdb) {
                if (UT64_MUL_OVFCHK (root_index_pages[i], page_size)) {
                        break;
                }
-               r_buf_seek (pdb->buf, root_index_pages[i] * page_size,
-                       R_BUF_SET);
+               r_buf_seek (pdb->buf, root_index_pages[i] * page_size, R_BUF_SET);
                r_buf_read (pdb->buf, p_tmp, page_size);
                p_tmp = (char *)p_tmp + page_size;
        }
@@ -516,8 +500,7 @@ static bool pdb7_parse(RBinPdb *pdb) {
        }
 
        pdb->pdb_streams2 = NULL;
-       if (!init_pdb7_root_stream (pdb, root_page_list, num_root_pages,
-               ePDB_STREAM_ROOT, root_size, page_size)) {
+       if (!init_pdb7_root_stream (pdb, root_page_list, num_root_pages, ePDB_STREAM_ROOT, root_size, page_size)) {
                R_LOG_ERROR ("Could not initialize root stream");
                goto error;
        }
@@ -676,106 +659,106 @@ static int simple_type_to_format(const SLF_SIMPLE_TYPE *simple_type, char **memb
                {
                        SimpleTypeKind kind = get_simple_type_kind (simple_type->simple_type);
                        switch (kind) {
-               case PDB_NONE:
-               case PDB_VOID:
-               case PDB_NOT_TRANSLATED:
-               case PDB_HRESULT:
+                       case PDB_NONE:
+                       case PDB_VOID:
+                       case PDB_NOT_TRANSLATED:
+                       case PDB_HRESULT:
                                return -1;
                                break;
-               case PDB_SIGNED_CHAR:
-               case PDB_NARROW_CHAR:
+                       case PDB_SIGNED_CHAR:
+                       case PDB_NARROW_CHAR:
                                *member_format = "c";
                                break;
-               case PDB_UNSIGNED_CHAR:
+                       case PDB_UNSIGNED_CHAR:
                                *member_format = "b";
                                break;
-               case PDB_SBYTE:
+                       case PDB_SBYTE:
                                *member_format = "n1";
                                break;
-               case PDB_BOOL8:
-               case PDB_BYTE:
+                       case PDB_BOOL8:
+                       case PDB_BYTE:
                                *member_format = "N1";
                                break;
-               case PDB_INT16_SHORT:
-               case PDB_INT16:
+                       case PDB_INT16_SHORT:
+                       case PDB_INT16:
                                *member_format = "n2";
                                break;
-               case PDB_UINT16_SHORT:
-               case PDB_UINT16:
-               case PDB_WIDE_CHAR: // TODO what ideal format for wchar?
-               case PDB_CHAR16:
-               case PDB_BOOL16:
+                       case PDB_UINT16_SHORT:
+                       case PDB_UINT16:
+                       case PDB_WIDE_CHAR: // TODO what ideal format for wchar?
+                       case PDB_CHAR16:
+                       case PDB_BOOL16:
                                *member_format = "N2";
                                break;
-               case PDB_INT32_LONG:
-               case PDB_INT32:
+                       case PDB_INT32_LONG:
+                       case PDB_INT32:
                                *member_format = "n4";
                                break;
-               case PDB_UINT32_LONG:
-               case PDB_UINT32:
-               case PDB_CHAR32:
-               case PDB_BOOL32:
+                       case PDB_UINT32_LONG:
+                       case PDB_UINT32:
+                       case PDB_CHAR32:
+                       case PDB_BOOL32:
                                *member_format = "N4";
                                break;
-               case PDB_INT64_QUAD:
-               case PDB_INT64:
+                       case PDB_INT64_QUAD:
+                       case PDB_INT64:
                                *member_format = "n8";
                                break;
-               case PDB_UINT64_QUAD:
-               case PDB_UINT64:
-               case PDB_BOOL64:
+                       case PDB_UINT64_QUAD:
+                       case PDB_UINT64:
+                       case PDB_BOOL64:
                                *member_format = "N8";
                                break;
-                       // TODO these when formatting for them will exist
-               case PDB_INT128_OCT:
-               case PDB_UINT128_OCT:
-               case PDB_INT128:
-               case PDB_UINT128:
-               case PDB_BOOL128:
+                               // TODO these when formatting for them will exist
+                       case PDB_INT128_OCT:
+                       case PDB_UINT128_OCT:
+                       case PDB_INT128:
+                       case PDB_UINT128:
+                       case PDB_BOOL128:
                                *member_format = "::::";
                                return -2;
                                ////////////////////////////////////
                                // TODO these when formatting for them will exist
                                // I assume complex are made up by 2 floats
-               case PDB_COMPLEX16:
+                       case PDB_COMPLEX16:
                                *member_format = "..";
                                return -2;
-               case PDB_COMPLEX32:
-               case PDB_COMPLEX32_PP:
+                       case PDB_COMPLEX32:
+                       case PDB_COMPLEX32_PP:
                                *member_format = ":";
                                return -2;
-               case PDB_COMPLEX48:
+                       case PDB_COMPLEX48:
                                *member_format = ":.";
                                return -2;
-               case PDB_COMPLEX64:
+                       case PDB_COMPLEX64:
                                *member_format = "::";
                                return -2;
-               case PDB_COMPLEX80:
+                       case PDB_COMPLEX80:
                                *member_format = "::..";
                                return -2;
-               case PDB_COMPLEX128:
+                       case PDB_COMPLEX128:
                                *member_format = "::::";
                                return -2;
 
-               case PDB_FLOAT32:
-               case PDB_FLOAT32_PP:
+                       case PDB_FLOAT32:
+                       case PDB_FLOAT32_PP:
                                *member_format = "f";
                                break;
-               case PDB_FLOAT64:
+                       case PDB_FLOAT64:
                                *member_format = "F";
                                break;
                                ////////////////////////////////////
                                // TODO these when formatting for them will exist
-               case PDB_FLOAT16:
+                       case PDB_FLOAT16:
                                *member_format = "..";
                                return -2;
-               case PDB_FLOAT48:
+                       case PDB_FLOAT48:
                                *member_format = ":.";
                                return -2;
-               case PDB_FLOAT80:
+                       case PDB_FLOAT80:
                                *member_format = "::..";
                                return -2;
-               case PDB_FLOAT128:
+                       case PDB_FLOAT128:
                                *member_format = "::::";
                                return -2;
                        default:
@@ -1349,7 +1332,7 @@ static void print_types_format(const RBinPdb *pdb, STpiStream *ss, const RList *
                r_strbuf_fini (&format);
                r_strbuf_fini (&member_names);
 
-       fail: // if we can't print whole type correctly, don't print at all
+fail: // if we can't print whole type correctly, don't print at all
                if (to_free_name) {
                        R_FREE (name);
                }
@@ -1454,7 +1437,9 @@ static void print_gvars(RBinPdb *pdb, ut64 img_base, PJ *pj, int format) {
                                pdb->cb_printf ("f pdb.%s = 0x%" PFMT64x " # %d %.*s\n",
                                        filtered_name,
                                        (ut64) (img_base + omap_remap ((omap)? (omap->stream): 0, gdata->offset + sctn_header->virtual_address)),
-                                       gdata->symtype, PDB_SIZEOF_SECTION_NAME, sctn_header->name);
+                                       gdata->symtype,
+                                       PDB_SIZEOF_SECTION_NAME,
+                                       sctn_header->name);
                                pdb->cb_printf ("\"fN pdb.%s %s\"\n", filtered_name, name);
                                free (filtered_name);
                                break;
@@ -1462,7 +1447,10 @@ static void print_gvars(RBinPdb *pdb, ut64 img_base, PJ *pj, int format) {
                        default:
                                pdb->cb_printf ("0x%08" PFMT64x "  %d  %.*s  %s\n",
                                        (ut64) (img_base + omap_remap ((omap)? (omap->stream): 0, gdata->offset + sctn_header->virtual_address)),
-                                       gdata->symtype, PDB_SIZEOF_SECTION_NAME, sctn_header->name, name);
+                                       gdata->symtype,
+                                       PDB_SIZEOF_SECTION_NAME,
+                                       sctn_header->name,
+                                       name);
                                break;
                        }
                        free (name);
index a4fa85939d31dabba0ac462081b1c05b6ca4814c..ab43e4109777594a5cb61ca1b7ed8abfc498d66a 100644 (file)
@@ -13,8 +13,10 @@ static bool checkExtract(void) {
 
 static bool download_and_write(SPDBDownloaderOpt *opt, const char *file) {
        char *dir = r_str_newf ("%s%s%s%s%s",
-               opt->symbol_store_path, R_SYS_DIR,
-               opt->dbg_file, R_SYS_DIR,
+               opt->symbol_store_path,
+               R_SYS_DIR,
+               opt->dbg_file,
+               R_SYS_DIR,
                opt->guid);
        if (!r_sys_mkdirp (dir)) {
                free (dir);
@@ -65,9 +67,12 @@ static int download(struct SPDBDownloader *pd) {
        }
 
        char *abspath_to_file = r_str_newf ("%s%s%s%s%s%s%s",
-               opt->symbol_store_path, R_SYS_DIR,
-               opt->dbg_file, R_SYS_DIR,
-               opt->guid, R_SYS_DIR,
+               opt->symbol_store_path,
+               R_SYS_DIR,
+               opt->dbg_file,
+               R_SYS_DIR,
+               opt->guid,
+               R_SYS_DIR,
                opt->dbg_file);
 
        if (r_file_exists (abspath_to_file)) {
@@ -81,9 +86,12 @@ static int download(struct SPDBDownloader *pd) {
                char *archive_name = strdup (opt->dbg_file);
                archive_name[strlen (archive_name) - 1] = '_';
                char *abspath_to_archive = r_str_newf ("%s%s%s%s%s%s%s",
-                       opt->symbol_store_path, R_SYS_DIR,
-                       opt->dbg_file, R_SYS_DIR,
-                       opt->guid, R_SYS_DIR,
+                       opt->symbol_store_path,
+                       R_SYS_DIR,
+                       opt->dbg_file,
+                       R_SYS_DIR,
+                       opt->guid,
+                       R_SYS_DIR,
                        archive_name);
 
                R_LOG_INFO ("Attempting to download compressed pdb in %s", abspath_to_archive);
@@ -204,8 +212,7 @@ int r_bin_pdb_download(RCore *core, PJ *pj, SPDBOptions *options) {
                pj_kb (pj, "download", (bool)ret);
                pj_end (pj);
        } else {
-               r_cons_printf (core->cons, "PDB \"%s\" download %s\n",
-                       opt.dbg_file, ret? "success": "failed");
+               r_cons_printf (core->cons, "PDB \"%s\" download %s\n", opt.dbg_file, ret? "success": "failed");
        }
        deinit_pdb_downloader (&pdb_downloader);
 
index 87ac0100ad50ea7ef438cb0390d57122c4bbacec..cee68d94a83d97bb4bc7a818790b0a0ae2b6c7be 100644 (file)
@@ -36,8 +36,7 @@ static void stream_file_read_pages(R_STREAM_FILE *stream_file, int start_indx, i
                        return;
                }
                r_buf_seek (stream_file->buf, page_offset, R_BUF_SET);
-               r_buf_read_at (stream_file->buf, page_offset,
-                       (ut8 *)res, stream_file->page_size);
+               r_buf_read_at (stream_file->buf, page_offset, (ut8 *)res, stream_file->page_size);
                res += stream_file->page_size;
        }
 }
@@ -106,10 +105,9 @@ void stream_file_get_data(R_STREAM_FILE *stream_file, char *data) {
        stream_file_seek (stream_file, pos, 0);
 }
 
-///////////////////////////////////////////////////////////////////////////////
-void stream_file_get_size(R_STREAM_FILE *stream_file, int *data_size) {
+int stream_file_get_size(R_STREAM_FILE *stream_file) {
        int pn_start = 0, off_start = 0;
        GET_PAGE (pn_start, off_start, stream_file->pos, stream_file->page_size);
        (void)pn_start; // hack for remove unused warning
-       *data_size = stream_file->end - off_start;
+       return stream_file->end - off_start;
 }
index dd5a93e1f8db625f0f572138873afebbbb3a7242..ab9a5a1742a06dda332d452ebcbad479310fd5c7 100644 (file)
@@ -7,23 +7,13 @@
 /// size = -1 (default value)
 /// pages_size = 0x1000 (default value)
 ////////////////////////////////////////////////////////////////////////////////
-int init_r_stream_file(R_STREAM_FILE *stream_file, RBuffer *buf, int *pages,
-                                                         int pages_amount, int size, int page_size);
+int init_r_stream_file(R_STREAM_FILE *stream_file, RBuffer *buf, int *pages, int pages_amount, int size, int page_size);
 
 // size by default = -1
-///////////////////////////////////////////////////////////////////////////////
 void stream_file_read(R_STREAM_FILE *stream_file, int size, char *res);
-
-///////////////////////////////////////////////////////////////////////////////
 void stream_file_seek(R_STREAM_FILE *stream_file, int offset, int whence);
-
-///////////////////////////////////////////////////////////////////////////////
 int stream_file_tell(R_STREAM_FILE *stream_file);
-
-///////////////////////////////////////////////////////////////////////////////
 void stream_file_get_data(R_STREAM_FILE *stream_file, char *data);
-
-///////////////////////////////////////////////////////////////////////////////
-void stream_file_get_size(R_STREAM_FILE *stream_file, int *data_size);
+int stream_file_get_size(R_STREAM_FILE *stream_file);
 
 #endif // STREAM_FILE_H
index d1091e6200a38e67c3c444349737c6637c605dab..50efeec735fe926044571e223165045d606676ca 100644 (file)
@@ -4,15 +4,17 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 void parse_pe_stream(STpiStream *ss, void *stream, R_STREAM_FILE *stream_file) {
-       int data_size = 0;
-       char *data = 0, *ptmp = 0;
+       char *ptmp = 0;
        int read_bytes = 0;
        SIMAGE_SECTION_HEADER *sctn_header = 0;
        SPEStream *pe_stream = (SPEStream *)stream;
        int sctn_header_size = 0;
 
-       stream_file_get_size (stream_file, &data_size);
-       data = (char *)malloc (data_size);
+       int data_size = stream_file_get_size (stream_file);
+       if (data_size < 1) {
+               return;
+       }
+       char *data = (char *)malloc (data_size);
        if (!data) {
                return;
        }
index 85396642dcc55cb564379875810352ac5ed03b61..d1bbc166fc1bd8ede154a83044c523fae087396c 100644 (file)
@@ -5,15 +5,8 @@
 #include "stream_file.h"
 
 static bool is_simple_type(int idx) {
-       ut32 value = (ut32)idx;
-       /*   https://llvm.org/docs/PDB/TpiStream.html#type-indices
-       .---------------------------.------.----------.
-       |           Unused          | Mode |   Kind   |
-       '---------------------------'------'----------'
-       |+32                        |+12   |+8        |+0
-        */
-       return value < 0x1000; // Simple types are below 0x1000
-       // return ((value & 0x00000000FFF00) <= 0x700 && (value & 0x00000000000FF) < 0x80);
+       /* https://llvm.org/docs/PDB/TpiStream.html#type-indices */
+       return ((ut32)idx) < 0x1000;
 }
 
 // Free a simple type that was dynamically allocated (tpi_idx == 0)
@@ -37,9 +30,6 @@ static void free_simple_type(SType *t) {
 static STypeInfo parse_simple_type(ut32 idx) {
        STypeInfo type = { 0 };
        SLF_SIMPLE_TYPE *simple_type = R_NEW0 (SLF_SIMPLE_TYPE);
-       if (!simple_type) {
-               return type;
-       }
        switch (idx) {
        case eT_NOTYPE: // uncharacterized type (no type)
                simple_type->size = 0;
@@ -748,7 +738,6 @@ static void get_sval_name(STpiStream *ss, SVal *val, char **name) {
                                SVal_LF_CHAR *lf_char;
                                lf_char = (SVal_LF_CHAR *)val->name_or_val;
                                *name = lf_char->name.name;
-                               //                      strcpy (name, lf_uchar->name.name);
                                break;
                        }
                case eLF_ULONG:
@@ -756,7 +745,6 @@ static void get_sval_name(STpiStream *ss, SVal *val, char **name) {
                                SVal_LF_ULONG *lf_ulong;
                                lf_ulong = (SVal_LF_ULONG *)val->name_or_val;
                                *name = lf_ulong->name.name;
-                               //                      strcpy (name, lf_ulong->name.name);
                                break;
                        }
                case eLF_LONG:
@@ -764,7 +752,6 @@ static void get_sval_name(STpiStream *ss, SVal *val, char **name) {
                                SVal_LF_LONG *lf_long;
                                lf_long = (SVal_LF_LONG *)val->name_or_val;
                                *name = lf_long->name.name;
-                               //                      strcpy (name, lf_long->name.name);
                                break;
                        }
                case eLF_USHORT:
@@ -772,7 +759,6 @@ static void get_sval_name(STpiStream *ss, SVal *val, char **name) {
                                SVal_LF_USHORT *lf_ushort;
                                lf_ushort = (SVal_LF_USHORT *)val->name_or_val;
                                *name = lf_ushort->name.name;
-                               //                      strcpy (name, lf_ushort->name.name);
                                break;
                        }
                case eLF_SHORT:
@@ -816,23 +802,17 @@ static int get_array_element_type(STpiStream *ss, void *type, void **ret_type) {
        if (is_simple_type (curr_idx)) {
                STypeInfo base_type = parse_simple_type (curr_idx);
                SType *base_ret_type = R_NEW0 (SType);
-               if (!base_ret_type) {
-                       *ret_type = 0;
-                       return false;
-               }
                base_ret_type->tpi_idx = 0;
                base_ret_type->length = 0;
                base_ret_type->type_data = base_type;
                *ret_type = base_ret_type;
-               return true; // check what are the return values used for
+               return 0;
        }
        curr_idx -= ss->ctx.base_idx;
        *ret_type = r_list_get_n (ss->ctx.types_list, curr_idx);
-
        return curr_idx;
 }
 
-///////////////////////////////////////////////////////////////////////////////
 static int get_array_index_type(STpiStream *ss, void *type, void **ret_type) {
        STypeInfo *t = (STypeInfo *)type;
        SLF_ARRAY *lf_array = (SLF_ARRAY *)t->type_info;
@@ -841,24 +821,17 @@ static int get_array_index_type(STpiStream *ss, void *type, void **ret_type) {
        if (is_simple_type (curr_idx)) {
                STypeInfo base_type = parse_simple_type (curr_idx);
                SType *base_ret_type = R_NEW0 (SType);
-               if (!base_ret_type) {
-                       *ret_type = 0;
-                       return false;
-               }
                base_ret_type->tpi_idx = 0;
                base_ret_type->length = 0;
                base_ret_type->type_data = base_type;
                *ret_type = base_ret_type;
-               return true; // check what are the return values used for
+               return 0;
        }
        curr_idx -= ss->ctx.base_idx;
        *ret_type = r_list_get_n (ss->ctx.types_list, curr_idx);
-
        return curr_idx;
 }
 
-///////////////////////////////////////////////////////////////////////////////
-// Again doesn't work for base types
 static int get_bitfield_base_type(STpiStream *ss, void *type, void **ret_type) {
        STypeInfo *t = (STypeInfo *)type;
        SLF_BITFIELD *lf = (SLF_BITFIELD *)t->type_info;
@@ -867,23 +840,17 @@ static int get_bitfield_base_type(STpiStream *ss, void *type, void **ret_type) {
        if (is_simple_type (curr_idx)) {
                STypeInfo base_type = parse_simple_type (curr_idx);
                SType *base_ret_type = R_NEW0 (SType);
-               if (!base_ret_type) {
-                       *ret_type = 0;
-                       return false;
-               }
                base_ret_type->tpi_idx = 0;
                base_ret_type->length = 0;
                base_ret_type->type_data = base_type;
                *ret_type = base_ret_type;
-               return true; // check what are the return values used for
+               return 0;
        }
        curr_idx -= ss->ctx.base_idx;
        *ret_type = r_list_get_n (ss->ctx.types_list, curr_idx);
-
        return curr_idx;
 }
 
-///////////////////////////////////////////////////////////////////////////////
 static int get_class_struct_derived(STpiStream *ss, void *type, void **ret_type) {
        STypeInfo *t = (STypeInfo *)type;
        SLF_STRUCTURE *lf = (SLF_STRUCTURE *)t->type_info;
@@ -919,19 +886,14 @@ static int get_mfunction_return_type(STpiStream *ss, void *type, void **ret_type
        if (is_simple_type (curr_idx)) {
                STypeInfo base_type = parse_simple_type (curr_idx);
                SType *base_ret_type = R_NEW0 (SType);
-               if (!base_ret_type) {
-                       *ret_type = 0;
-                       return false;
-               }
                base_ret_type->tpi_idx = 0;
                base_ret_type->length = 0;
                base_ret_type->type_data = base_type;
                *ret_type = base_ret_type;
-               return true; // check what are the return values used for
+               return 0;
        }
        curr_idx -= ss->ctx.base_idx;
        *ret_type = r_list_get_n (ss->ctx.types_list, curr_idx);
-
        return curr_idx;
 }
 
@@ -990,22 +952,17 @@ static int get_modifier_modified_type(STpiStream *ss, void *type, void **ret_typ
        if (is_simple_type (curr_idx)) {
                STypeInfo base_type = parse_simple_type (curr_idx);
                SType *base_ret_type = R_NEW0 (SType);
-               if (!base_ret_type) {
-                       *ret_type = 0;
-                       return false;
-               }
                base_ret_type->tpi_idx = 0;
                base_ret_type->length = 0;
                base_ret_type->type_data = base_type;
                *ret_type = base_ret_type;
-               return true; // check what are the return values used for
+               return 0;
        }
        curr_idx -= ss->ctx.base_idx;
        *ret_type = r_list_get_n (ss->ctx.types_list, curr_idx);
        return curr_idx;
 }
 
-///////////////////////////////////////////////////////////////////////////////
 static int get_pointer_utype(STpiStream *ss, void *type, void **ret_type) {
        STypeInfo *t = (STypeInfo *)type;
        SLF_POINTER *lf = (SLF_POINTER *)t->type_info;
@@ -1014,19 +971,14 @@ static int get_pointer_utype(STpiStream *ss, void *type, void **ret_type) {
        if (is_simple_type (curr_idx)) {
                STypeInfo base_type = parse_simple_type (curr_idx);
                SType *base_ret_type = R_NEW0 (SType);
-               if (!base_ret_type) {
-                       *ret_type = 0;
-                       return false;
-               }
                base_ret_type->tpi_idx = 0;
                base_ret_type->length = 0;
                base_ret_type->type_data = base_type;
                *ret_type = base_ret_type;
-               return true; // check what are the return values used for
+               return 0;
        }
        curr_idx -= ss->ctx.base_idx;
        *ret_type = r_list_get_n (ss->ctx.types_list, curr_idx);
-
        return curr_idx;
 }
 
@@ -1042,7 +994,7 @@ static int get_procedure_return_type(STpiStream *ss, void *type, void **ret_type
                base_ret_type->length = 0;
                base_ret_type->type_data = base_type;
                *ret_type = base_ret_type;
-               return true; // check what are the return values used for
+               return 0;
        }
        curr_idx -= ss->ctx.base_idx;
        *ret_type = r_list_get_n (ss->ctx.types_list, curr_idx);
@@ -1058,15 +1010,11 @@ static int get_procedure_arglist(STpiStream *ss, void *type, void **ret_type) {
        if (is_simple_type (curr_idx)) {
                STypeInfo base_type = parse_simple_type (curr_idx);
                SType *base_ret_type = R_NEW0 (SType);
-               if (!base_ret_type) {
-                       *ret_type = 0;
-                       return false;
-               }
                base_ret_type->tpi_idx = 0;
                base_ret_type->length = 0;
                base_ret_type->type_data = base_type;
                *ret_type = base_ret_type;
-               return true; // check what are the return values used for
+               return 0;
        }
        curr_idx -= ss->ctx.base_idx;
        *ret_type = r_list_get_n (ss->ctx.types_list, curr_idx);
@@ -1082,15 +1030,11 @@ static int get_member_index(STpiStream *ss, void *type, void **ret_type) {
        if (is_simple_type (curr_idx)) {
                STypeInfo base_type = parse_simple_type (curr_idx);
                SType *base_ret_type = R_NEW0 (SType);
-               if (!base_ret_type) {
-                       *ret_type = 0;
-                       return false;
-               }
                base_ret_type->tpi_idx = 0;
                base_ret_type->length = 0;
                base_ret_type->type_data = base_type;
                *ret_type = base_ret_type;
-               return true; // check what are the return values used for
+               return 0;
        }
        curr_idx -= ss->ctx.base_idx;
        *ret_type = r_list_get_n (ss->ctx.types_list, curr_idx);
@@ -1106,15 +1050,11 @@ static int get_nesttype_index(STpiStream *ss, void *type, void **ret_type) {
        if (is_simple_type (curr_idx)) {
                STypeInfo base_type = parse_simple_type (curr_idx);
                SType *base_ret_type = R_NEW0 (SType);
-               if (!base_ret_type) {
-                       *ret_type = 0;
-                       return false;
-               }
                base_ret_type->tpi_idx = 0;
                base_ret_type->length = 0;
                base_ret_type->type_data = base_type;
                *ret_type = base_ret_type;
-               return true; // check what are the return values used for
+               return 0;
        }
        curr_idx -= ss->ctx.base_idx;
        *ret_type = r_list_get_n (ss->ctx.types_list, curr_idx);
@@ -1130,15 +1070,11 @@ static int get_onemethod_index(STpiStream *ss, void *type, void **ret_type) {
        if (is_simple_type (curr_idx)) {
                STypeInfo base_type = parse_simple_type (curr_idx);
                SType *base_ret_type = R_NEW0 (SType);
-               if (!base_ret_type) {
-                       *ret_type = 0;
-                       return false;
-               }
                base_ret_type->tpi_idx = 0;
                base_ret_type->length = 0;
                base_ret_type->type_data = base_type;
                *ret_type = base_ret_type;
-               return true; // check what are the return values used for
+               return 0;
        }
        curr_idx -= ss->ctx.base_idx;
        *ret_type = r_list_get_n (ss->ctx.types_list, curr_idx);
@@ -1154,15 +1090,11 @@ static int get_method_mlist(STpiStream *ss, void *type, void **ret_type) {
        if (is_simple_type (curr_idx)) {
                STypeInfo base_type = parse_simple_type (curr_idx);
                SType *base_ret_type = R_NEW0 (SType);
-               if (!base_ret_type) {
-                       *ret_type = 0;
-                       return false;
-               }
                base_ret_type->tpi_idx = 0;
                base_ret_type->length = 0;
                base_ret_type->type_data = base_type;
                *ret_type = base_ret_type;
-               return true; // check what are the return values used for
+               return 0;
        }
        curr_idx -= ss->ctx.base_idx;
        *ret_type = r_list_get_n (ss->ctx.types_list, curr_idx);
@@ -1170,7 +1102,6 @@ static int get_method_mlist(STpiStream *ss, void *type, void **ret_type) {
        return curr_idx;
 }
 
-// XXX this function returns bool and int at the same time wtf this is very wrong
 static int get_enum_utype(STpiStream *ss, void *type, void **ret_type) {
        STypeInfo *t = (STypeInfo *)type;
        SLF_ENUM *lf = (SLF_ENUM *)t->type_info;
@@ -1179,15 +1110,11 @@ static int get_enum_utype(STpiStream *ss, void *type, void **ret_type) {
        if (is_simple_type (curr_idx)) {
                STypeInfo base_type = parse_simple_type (curr_idx);
                SType *base_ret_type = R_NEW0 (SType);
-               if (!base_ret_type) {
-                       *ret_type = 0;
-                       return false;
-               }
                base_ret_type->tpi_idx = 0;
                base_ret_type->length = 0;
                base_ret_type->type_data = base_type;
                *ret_type = base_ret_type;
-               return true; // check what are the return values used for
+               return 0;
        }
        curr_idx -= ss->ctx.base_idx;
        *ret_type = r_list_get_n (ss->ctx.types_list, curr_idx);
@@ -1210,9 +1137,8 @@ static void get_union_members(STpiStream *ss, void *type, RList **l) {
        if (!lf_union || lf_union->field_list == 0) {
                *l = 0;
        } else {
-               SType *tmp = 0;
                indx = lf_union->field_list - ss->ctx.base_idx;
-               tmp = (SType *)r_list_get_n (ss->ctx.types_list, indx);
+               SType *tmp = (SType *)r_list_get_n (ss->ctx.types_list, indx);
                *l = tmp? ((SLF_FIELDLIST *)tmp->type_data.type_info)->substructs: NULL;
        }
 }
@@ -1225,9 +1151,8 @@ static void get_struct_class_members(STpiStream *ss, void *type, RList **l) {
        if (!lf || lf->field_list == 0) {
                *l = 0;
        } else {
-               SType *tmp = 0;
                indx = lf->field_list - ss->ctx.base_idx;
-               tmp = (SType *)r_list_get_n (ss->ctx.types_list, indx);
+               SType *tmp = (SType *)r_list_get_n (ss->ctx.types_list, indx);
                *l = tmp? ((SLF_FIELDLIST *)tmp->type_data.type_info)->substructs: NULL;
        }
 }
@@ -1579,7 +1504,7 @@ static void free_lf_member(STpiStream *ss, void *type_info) {
 static void free_lf_fieldlist(STpiStream *ss, void *type) {
        STypeInfo *t = (STypeInfo *)type;
        SLF_FIELDLIST *lf_fieldlist = (SLF_FIELDLIST *)t->type_info;
-       STypeInfo *type_info = 0;
+       STypeInfo *type_info = NULL;
        RListIter *it = r_list_iterator (lf_fieldlist->substructs);
        while (r_list_iter_next (it)) {
                type_info = (STypeInfo *)r_list_iter_get (it);
@@ -1640,10 +1565,10 @@ static void free_lf_vtshape(STpiStream *ss, void *type) {
 }
 
 static void free_tpi_stream(STpiStream *ss, void *stream) {
-       SType *type = NULL;
        RListIter *it = r_list_iterator (ss->types);
+       // TODO: is there any reason to use this ugly r_list_iter_next loop instead of r_list_foreach_safe? .. oh well maybe we can just call r_list_free if the iter data destructor callback is properly set we shouldnt be doing all those hacks
        while (r_list_iter_next (it)) {
-               type = (SType *)r_list_iter_get (it);
+               SType *type = (SType *)r_list_iter_get (it);
                if (!type) {
                        continue;
                }
@@ -1701,7 +1626,6 @@ static void get_pointer_print_type(STpiStream *ss, void *type, char **name) {
                ti = &t->type_data;
                ti->get_print_type (ss, ti, &tmp_name);
        }
-
        *name = r_str_newf ("%s*", tmp_name? tmp_name: "");
        free (tmp_name);
 }
@@ -1784,18 +1708,12 @@ static void get_enum_print_type(STpiStream *ss, void *type, char **name) {
 static void get_class_struct_print_type(STpiStream *ss, void *type, char **name) {
        STypeInfo *ti = (STypeInfo *)type;
        char *tmp_name = NULL;
-       const char *tmp1 = NULL;
 
        ELeafType lt = ti->leaf_type;
        ti->get_name (ss, ti, &tmp_name);
 
-       if (lt == eLF_CLASS) {
-               tmp1 = "class ";
-       } else {
-               tmp1 = "struct ";
-       }
-
-       *name = r_str_newf ("%s%s", tmp1, tmp_name? tmp_name: "");
+       const char *tmp1 = (lt == eLF_CLASS)? "class": "struct";
+       *name = r_str_newf ("%s %s", tmp1, tmp_name? tmp_name: "");
 }
 
 static void get_arglist_print_type(STpiStream *ss, void *type, char **name) {
@@ -1905,7 +1823,7 @@ static void get_member_print_type(STpiStream *ss, void *type, char **name) {
 static void get_onemethod_print_type(STpiStream *ss, void *type, char **name) {
        STypeInfo *ti = (STypeInfo *)type;
        SType *t = 0;
-       char *tmp_name = 0;
+       char *tmp_name = NULL;
 
        ti->get_index (ss, ti, (void **)&t);
        if (t->type_data.leaf_type == eLF_SIMPLE_TYPE) {
@@ -1932,29 +1850,34 @@ void deinit_scstring(SCString *cstr) {
        free (cstr->name);
 }
 
-///////////////////////////////////////////////////////////////////////////////
-int parse_sctring(SCString *sctr, uint8_t *leaf_data, unsigned int *read_bytes, unsigned int len) {
-       unsigned int c = 0;
+int parse_sctring(SCString *sctr, ut8 *leaf_data, ut32 *read_bytes, ut32 len) {
+       ut32 c = 0;
        sctr->name = NULL;
        sctr->size = 0;
        while (*leaf_data) {
-               CAN_READ ((*read_bytes + c), 1, len);
+               if (!can_read (*read_bytes + c, 1, len)) {
+                       return 0;
+               }
                c++;
                leaf_data++;
        }
-       CAN_READ (*read_bytes, 1, len);
+       if (!can_read (*read_bytes, 1, len)) {
+               return 0;
+       }
        leaf_data += 1;
-       (*read_bytes) += (c + 1);
+       *read_bytes += (c + 1);
        init_scstring (sctr, c + 1, (char *)leaf_data - (c + 1));
        return 1;
 }
 
-///////////////////////////////////////////////////////////////////////////////
-static int parse_sval(SVal *val, uint8_t *leaf_data, unsigned int *read_bytes, unsigned int len) {
+static int parse_sval(SVal *val, ut8 *leaf_data, ut32 *read_bytes, ut32 len) {
        val->name_or_val = 0;
-
-       READ2 (*read_bytes, len, val->value_or_type, leaf_data, ut16);
-
+       if (!can_read (*read_bytes, 2, len)) {
+               return 0;
+       }
+       val->value_or_type = r_read_le16 (leaf_data);
+       leaf_data += 2;
+       *read_bytes += 2;
        if (val->value_or_type < eLF_CHAR) {
                SCString *sctr = R_NEW0 (SCString);
                parse_sctring (sctr, leaf_data, read_bytes, len);
@@ -1963,21 +1886,27 @@ static int parse_sval(SVal *val, uint8_t *leaf_data, unsigned int *read_bytes, u
                switch (val->value_or_type) {
                case eLF_UQUADWORD:
                        {
+                               if (!can_read (*read_bytes, 8, len)) {
+                                       return 0;
+                               }
                                SVal_LF_UQUADWORD lf_uqword;
-                               READ8 (*read_bytes, len, lf_uqword.value, leaf_data, st64);
+                               lf_uqword.value = r_read_le64 (leaf_data);
+                               leaf_data += 8;
+                               *read_bytes += 8;
                                parse_sctring (&lf_uqword.name, leaf_data, read_bytes, len);
                                val->name_or_val = R_NEW0 (SVal_LF_UQUADWORD);
-                               if (!val->name_or_val) {
-                                       free (lf_uqword.name.name);
-                                       break;
-                               }
                                memcpy (val->name_or_val, &lf_uqword, sizeof (SVal_LF_UQUADWORD));
                                break;
                        }
                case eLF_QUADWORD:
                        {
+                               if (!can_read (*read_bytes, 8, len)) {
+                                       return 0;
+                               }
                                SVal_LF_QUADWORD lf_qword;
-                               READ8 (*read_bytes, len, lf_qword.value, leaf_data, st64);
+                               lf_qword.value = (st64)r_read_le64 (leaf_data);
+                               leaf_data += 8;
+                               *read_bytes += 8;
                                parse_sctring (&lf_qword.name, leaf_data, read_bytes, len);
                                val->name_or_val = malloc (sizeof (SVal_LF_QUADWORD));
                                if (!val->name_or_val) {
@@ -1988,8 +1917,13 @@ static int parse_sval(SVal *val, uint8_t *leaf_data, unsigned int *read_bytes, u
                        }
                case eLF_CHAR:
                        {
+                               if (!can_read (*read_bytes, 1, len)) {
+                                       return 0;
+                               }
                                SVal_LF_CHAR lf_char;
-                               READ1 (*read_bytes, len, lf_char.value, leaf_data, st8);
+                               lf_char.value = (st8)leaf_data[0];
+                               leaf_data += 1;
+                               *read_bytes += 1;
                                parse_sctring (&lf_char.name, leaf_data, read_bytes, len);
                                val->name_or_val = malloc (sizeof (SVal_LF_CHAR));
                                if (!val->name_or_val) {
@@ -2000,12 +1934,13 @@ static int parse_sval(SVal *val, uint8_t *leaf_data, unsigned int *read_bytes, u
                        }
                case eLF_LONG:
                        {
+                               if (!can_read (*read_bytes, 4, len)) {
+                                       return 0;
+                               }
                                SVal_LF_LONG lf_long;
-                               lf_long.value = 0;
-                               // long = 4 bytes for Windows, but not in Linux x64,
-                               // so here is using int instead of long when
-                               // reading long value
-                               READ4 (*read_bytes, len, lf_long.value, leaf_data, st32);
+                               lf_long.value = (st32)r_read_le32 (leaf_data);
+                               leaf_data += 4;
+                               *read_bytes += 4;
                                parse_sctring (&lf_long.name, leaf_data, read_bytes, len);
                                val->name_or_val = malloc (sizeof (SVal_LF_LONG));
                                if (!val->name_or_val) {
@@ -2016,12 +1951,13 @@ static int parse_sval(SVal *val, uint8_t *leaf_data, unsigned int *read_bytes, u
                        }
                case eLF_ULONG:
                        {
+                               if (!can_read (*read_bytes, 4, len)) {
+                                       return 0;
+                               }
                                SVal_LF_ULONG lf_ulong;
-                               lf_ulong.value = 0;
-                               // unsigned long = 4 bytes for Windows, but not in Linux x64,
-                               // so here is using unsigned int instead of unsigned long when
-                               // reading ulong value
-                               READ4 (*read_bytes, len, lf_ulong.value, leaf_data, ut32);
+                               lf_ulong.value = r_read_le32 (leaf_data);
+                               leaf_data += 4;
+                               *read_bytes += 4;
                                parse_sctring (&lf_ulong.name, leaf_data, read_bytes, len);
                                val->name_or_val = malloc (sizeof (SVal_LF_ULONG));
                                if (!val->name_or_val) {
@@ -2032,8 +1968,13 @@ static int parse_sval(SVal *val, uint8_t *leaf_data, unsigned int *read_bytes, u
                        }
                case eLF_SHORT:
                        {
+                               if (!can_read (*read_bytes, 2, len)) {
+                                       return 0;
+                               }
                                SVal_LF_SHORT lf_short;
-                               READ2 (*read_bytes, len, lf_short.value, leaf_data, st16);
+                               lf_short.value = (st16)r_read_le16 (leaf_data);
+                               leaf_data += 2;
+                               *read_bytes += 2;
                                parse_sctring (&lf_short.name, leaf_data, read_bytes, len);
                                val->name_or_val = malloc (sizeof (SVal_LF_SHORT));
                                if (!val->name_or_val) {
@@ -2044,8 +1985,13 @@ static int parse_sval(SVal *val, uint8_t *leaf_data, unsigned int *read_bytes, u
                        }
                case eLF_USHORT:
                        {
+                               if (!can_read (*read_bytes, 2, len)) {
+                                       return 0;
+                               }
                                SVal_LF_USHORT lf_ushort;
-                               READ2 (*read_bytes, len, lf_ushort.value, leaf_data, ut16);
+                               lf_ushort.value = r_read_le16 (leaf_data);
+                               leaf_data += 2;
+                               *read_bytes += 2;
                                parse_sctring (&lf_ushort.name, leaf_data, read_bytes, len);
                                val->name_or_val = malloc (sizeof (SVal_LF_USHORT));
                                if (!val->name_or_val) {
@@ -2055,111 +2001,118 @@ static int parse_sval(SVal *val, uint8_t *leaf_data, unsigned int *read_bytes, u
                                break;
                        }
                default:
-                       printf ("parse_sval: Skipping unsupported type (%d)\n", val->value_or_type);
+                       R_LOG_WARN ("parse_sval: Skipping unsupported type (%d)", val->value_or_type);
                        return 0;
                }
        }
-
        return 1;
 }
 
-///////////////////////////////////////////////////////////////////////////////
-static int parse_lf_enumerate(SLF_ENUMERATE *lf_enumerate, uint8_t *leaf_data, unsigned int *read_bytes, unsigned int len) {
-       unsigned int read_bytes_before = 0, tmp_read_bytes_before = 0;
-
+static int parse_lf_enumerate(SLF_ENUMERATE *lf_enumerate, const ut8 *leaf_data, ut32 *read_bytes, ut32 len) {
+       const ut32 start = *read_bytes;
+       if (!can_read (*read_bytes, 2, len)) {
+               return 0;
+       }
        lf_enumerate->enum_value.name_or_val = 0;
-
-       read_bytes_before = *read_bytes;
-       READ2 (*read_bytes, len, lf_enumerate->fldattr.fldattr, leaf_data, ut16);
-
-       tmp_read_bytes_before = *read_bytes;
-       parse_sval (&lf_enumerate->enum_value, leaf_data, read_bytes, len);
-       leaf_data += (*read_bytes - tmp_read_bytes_before);
-
-       PEEK_READ1 (*read_bytes, len, lf_enumerate->pad, leaf_data, ut8);
-       PAD_ALIGN (lf_enumerate->pad, *read_bytes, leaf_data, len);
-
-       return (*read_bytes - read_bytes_before);
+       lf_enumerate->fldattr.fldattr = r_read_le16 (leaf_data);
+       leaf_data += 2;
+       *read_bytes += 2;
+       ut32 before = *read_bytes;
+       parse_sval (&lf_enumerate->enum_value, (ut8 *)leaf_data, read_bytes, len);
+       leaf_data += (*read_bytes - before);
+       lf_enumerate->pad = (len > *read_bytes)? leaf_data[0]: 0;
+       if (!pad_align (lf_enumerate->pad, (ut8 **)&leaf_data, read_bytes, len)) {
+               return 0;
+       }
+       return *read_bytes - start;
 }
 
-///////////////////////////////////////////////////////////////////////////////
-static int parse_lf_nesttype(SLF_NESTTYPE *lf_nesttype, uint8_t *leaf_data, unsigned int *read_bytes, unsigned int len) {
-       unsigned int read_bytes_before = *read_bytes;
-
+static int parse_lf_nesttype(SLF_NESTTYPE *lf_nesttype, const ut8 *leaf_data, ut32 *read_bytes, ut32 len) {
+       const ut32 start = *read_bytes;
+       const ut32 fixed_size = 6;
+       if (!can_read (*read_bytes, fixed_size, len)) {
+               return 0;
+       }
        lf_nesttype->name.name = 0;
-
-       READ2 (*read_bytes, len, lf_nesttype->pad, leaf_data, ut16);
-       READ4 (*read_bytes, len, lf_nesttype->index, leaf_data, ut16);
-
-       parse_sctring (&lf_nesttype->name, leaf_data, read_bytes, len);
-
-       return *read_bytes - read_bytes_before;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-static int parse_lf_method(SLF_METHOD *lf_method, uint8_t *leaf_data, unsigned int *read_bytes, unsigned int len) {
-       unsigned int read_bytes_before = *read_bytes, tmp_read_bytes_before = 0;
-
+       lf_nesttype->pad = r_read_le16 (leaf_data);
+       lf_nesttype->index = r_read_le32 (leaf_data + 2);
+       leaf_data += fixed_size;
+       *read_bytes += fixed_size;
+       parse_sctring (&lf_nesttype->name, (ut8 *)leaf_data, read_bytes, len);
+       return *read_bytes - start;
+}
+
+static int parse_lf_method(SLF_METHOD *lf_method, const ut8 *leaf_data, ut32 *read_bytes, ut32 len) {
+       const ut32 start = *read_bytes;
+       const ut32 fixed_size = 6;
+       if (!can_read (*read_bytes, fixed_size, len)) {
+               return 0;
+       }
        lf_method->name.name = 0;
-
-       READ2 (*read_bytes, len, lf_method->count, leaf_data, ut16);
-       READ4 (*read_bytes, len, lf_method->mlist, leaf_data, ut32);
-
-       tmp_read_bytes_before = *read_bytes;
-       parse_sctring (&lf_method->name, leaf_data, read_bytes, len);
-       leaf_data += (*read_bytes - tmp_read_bytes_before);
-
-       PEEK_READ1 (*read_bytes, len, lf_method->pad, leaf_data, ut8);
-       PAD_ALIGN (lf_method->pad, *read_bytes, leaf_data, len);
-
-       return *read_bytes - read_bytes_before;
+       lf_method->count = r_read_le16 (leaf_data);
+       lf_method->mlist = r_read_le32 (leaf_data + 2);
+       leaf_data += fixed_size;
+       *read_bytes += fixed_size;
+       ut32 before = *read_bytes;
+       parse_sctring (&lf_method->name, (ut8 *)leaf_data, read_bytes, len);
+       leaf_data += (*read_bytes - before);
+       lf_method->pad = (len > *read_bytes)? leaf_data[0]: 0;
+       if (!pad_align (lf_method->pad, (ut8 **)&leaf_data, read_bytes, len)) {
+               return 0;
+       }
+       return *read_bytes - start;
 }
 
-///////////////////////////////////////////////////////////////////////////////
-static int parse_lf_member(SLF_MEMBER *lf_member, uint8_t *leaf_data, unsigned int *read_bytes, unsigned int len) {
-       int read_bytes_before = *read_bytes, tmp_read_bytes_before = 0;
-
+static int parse_lf_member(SLF_MEMBER *lf_member, const ut8 *leaf_data, ut32 *read_bytes, ut32 len) {
+       const ut32 start = *read_bytes;
+       const ut32 fixed_size = 6;
+       if (!can_read (*read_bytes, fixed_size, len)) {
+               return 0;
+       }
        lf_member->offset.name_or_val = 0;
-
-       READ2 (*read_bytes, len, lf_member->fldattr.fldattr, leaf_data, ut16);
-       READ4 (*read_bytes, len, lf_member->index, leaf_data, ut32);
-
-       tmp_read_bytes_before = *read_bytes;
-       parse_sval (&lf_member->offset, leaf_data, read_bytes, len);
-       leaf_data += (*read_bytes - tmp_read_bytes_before);
-
-       PEEK_READ1 (*read_bytes, len, lf_member->pad, leaf_data, ut8);
-       PAD_ALIGN (lf_member->pad, *read_bytes, leaf_data, len);
-
-       return (*read_bytes - read_bytes_before);
+       lf_member->fldattr.fldattr = r_read_le16 (leaf_data);
+       lf_member->index = r_read_le32 (leaf_data + 2);
+       leaf_data += fixed_size;
+       *read_bytes += fixed_size;
+       ut32 before = *read_bytes;
+       parse_sval (&lf_member->offset, (ut8 *)leaf_data, read_bytes, len);
+       leaf_data += (*read_bytes - before);
+       lf_member->pad = (len > *read_bytes)? leaf_data[0]: 0;
+       if (!pad_align (lf_member->pad, (ut8 **)&leaf_data, read_bytes, len)) {
+               return 0;
+       }
+       return *read_bytes - start;
 }
 
-///////////////////////////////////////////////////////////////////////////////
-static int parse_lf_onemethod(SLF_ONEMETHOD *lf_onemethod, uint8_t *leaf_data, unsigned int *read_bytes, unsigned int len) {
-       int read_bytes_before = *read_bytes;
-       int tmp_before_read_bytes = 0;
-
+static int parse_lf_onemethod(SLF_ONEMETHOD *lf_onemethod, const ut8 *leaf_data, ut32 *read_bytes, ut32 len) {
+       const ut32 start = *read_bytes;
+       const ut32 fixed_size = 6;
+       if (!can_read (*read_bytes, fixed_size, len)) {
+               return 0;
+       }
        lf_onemethod->val.str_data.name = 0;
        lf_onemethod->val.val = 0;
-
-       READ2 (*read_bytes, len, lf_onemethod->fldattr.fldattr, leaf_data, ut16);
-       READ4 (*read_bytes, len, lf_onemethod->index, leaf_data, ut32);
-
-       // lf_onemethod->fldattr.fldattr = SWAP_UINT16 (lf_onemethod->fldattr.fldattr);
-
+       lf_onemethod->fldattr.fldattr = r_read_le16 (leaf_data);
+       lf_onemethod->index = r_read_le32 (leaf_data + 2);
+       leaf_data += fixed_size;
+       *read_bytes += fixed_size;
        if ((lf_onemethod->fldattr.bits.mprop == eMTintro) ||
                (lf_onemethod->fldattr.bits.mprop == eMTpureintro)) {
-               READ4 (*read_bytes, len, lf_onemethod->val.val, leaf_data, ut32);
+               if (!can_read (*read_bytes, 4, len)) {
+                       return 0;
+               }
+               lf_onemethod->val.val = r_read_le32 (leaf_data);
+               leaf_data += 4;
+               *read_bytes += 4;
        }
-
-       tmp_before_read_bytes = *read_bytes;
-       parse_sctring (&(lf_onemethod->val.str_data), leaf_data, read_bytes, len);
-       leaf_data += (*read_bytes - tmp_before_read_bytes);
-
-       PEEK_READ1 (*read_bytes, len, lf_onemethod->pad, leaf_data, ut8);
-       PAD_ALIGN (lf_onemethod->pad, *read_bytes, leaf_data, len);
-
-       return (*read_bytes - read_bytes_before);
+       ut32 before = *read_bytes;
+       parse_sctring (&(lf_onemethod->val.str_data), (ut8 *)leaf_data, read_bytes, len);
+       leaf_data += (*read_bytes - before);
+       lf_onemethod->pad = (len > *read_bytes)? leaf_data[0]: 0;
+       if (!pad_align (lf_onemethod->pad, (ut8 **)&leaf_data, read_bytes, len)) {
+               return 0;
+       }
+       return *read_bytes - start;
 }
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -2328,14 +2281,8 @@ static void init_stype_info(STypeInfo *type_info) {
 
 #define PARSE_LF2(lf_type, lf_func_name, type) \
        { \
-               STypeInfo *type_info = (STypeInfo *)malloc (sizeof (STypeInfo)); \
-               if (!type_info) \
-                       return 0; \
-               lf_type *lf = (lf_type *)malloc (sizeof (lf_type)); \
-               if (!lf) { \
-                       free (type_info); \
-                       return 0; \
-               } \
+               STypeInfo *type_info = R_NEW0 (STypeInfo); \
+               lf_type *lf = R_NEW0 (lf_type); \
                curr_read_bytes = parse_ ## lf_func_name (lf, p, read_bytes, len); \
                type_info->type_info = (void *)lf; \
                type_info->leaf_type = type; \
@@ -2343,16 +2290,17 @@ static void init_stype_info(STypeInfo *type_info) {
                r_list_append (lf_fieldlist->substructs, type_info); \
        }
 
-///////////////////////////////////////////////////////////////////////////////
-static int parse_lf_fieldlist(SLF_FIELDLIST *lf_fieldlist, uint8_t *leaf_data, unsigned int *read_bytes, unsigned int len) {
-       ELeafType leaf_type;
+static int parse_lf_fieldlist(SLF_FIELDLIST *lf_fieldlist, const ut8 *leaf_data, ut32 *read_bytes, ut32 len) {
        int curr_read_bytes = 0;
-       uint8_t *p = leaf_data;
-
+       const ut8 *p = leaf_data;
        lf_fieldlist->substructs = r_list_new ();
-
        while (*read_bytes <= len) {
-               READ2 (*read_bytes, len, leaf_type, p, ut16);
+               if (!can_read (*read_bytes, 2, len)) {
+                       return 0;
+               }
+               ut16 leaf_type = r_read_le16 (p);
+               p += 2;
+               *read_bytes += 2;
                switch (leaf_type) {
                case eLF_ENUMERATE:
                        PARSE_LF2 (SLF_ENUMERATE, lf_enumerate, eLF_ENUMERATE);
@@ -2370,10 +2318,8 @@ static int parse_lf_fieldlist(SLF_FIELDLIST *lf_fieldlist, uint8_t *leaf_data, u
                        PARSE_LF2 (SLF_ONEMETHOD, lf_onemethod, eLF_ONEMETHOD);
                        break;
                default:
-                       //                      printf ("unsupported leaf type in parse_lf_fieldlist()\n");
                        return 0;
                }
-
                if (curr_read_bytes == 0) {
                        break;
                }
@@ -2382,228 +2328,255 @@ static int parse_lf_fieldlist(SLF_FIELDLIST *lf_fieldlist, uint8_t *leaf_data, u
        return 0;
 }
 
-///////////////////////////////////////////////////////////////////////////////
-static int parse_lf_enum(SLF_ENUM *lf_enum, uint8_t *leaf_data, unsigned int *read_bytes, unsigned int len) {
-       unsigned int tmp_before_read_bytes = *read_bytes;
-       unsigned int before_read_bytes = 0;
-
+static int parse_lf_enum(SLF_ENUM *lf_enum, const ut8 *leaf_data, ut32 *read_bytes, ut32 len) {
+       const ut32 start = *read_bytes;
+       const ut32 fixed_size = 12;
+       if (!can_read (*read_bytes, fixed_size, len)) {
+               return 0;
+       }
        lf_enum->name.name = 0;
-
-       READ2 (*read_bytes, len, lf_enum->count, leaf_data, ut16);
-       READ2 (*read_bytes, len, lf_enum->prop.cv_property, leaf_data, ut16);
-       READ4 (*read_bytes, len, lf_enum->utype, leaf_data, ut32);
-       READ4 (*read_bytes, len, lf_enum->field_list, leaf_data, ut32);
-
-       // lf_enum->prop.cv_property = SWAP_UINT16 (lf_enum->prop.cv_property);
-       before_read_bytes = *read_bytes;
-       parse_sctring (&lf_enum->name, leaf_data, read_bytes, len);
-       leaf_data += (*read_bytes - before_read_bytes);
-
-       PEEK_READ1 (*read_bytes, len, lf_enum->pad, leaf_data, ut8);
-       PAD_ALIGN (lf_enum->pad, *read_bytes, leaf_data, len);
-
-       return *read_bytes - tmp_before_read_bytes;
+       lf_enum->count = r_read_le16 (leaf_data);
+       lf_enum->prop.cv_property = r_read_le16 (leaf_data + 2);
+       lf_enum->utype = r_read_le32 (leaf_data + 4);
+       lf_enum->field_list = r_read_le32 (leaf_data + 8);
+       leaf_data += fixed_size;
+       *read_bytes += fixed_size;
+       ut32 before = *read_bytes;
+       parse_sctring (&lf_enum->name, (ut8 *)leaf_data, read_bytes, len);
+       leaf_data += (*read_bytes - before);
+       lf_enum->pad = (len > *read_bytes)? leaf_data[0]: 0;
+       if (!pad_align (lf_enum->pad, (ut8 **)&leaf_data, read_bytes, len)) {
+               return 0;
+       }
+       return *read_bytes - start;
 }
 
-///////////////////////////////////////////////////////////////////////////////
-static int parse_lf_class(SLF_CLASS *lf_class, uint8_t *leaf_data, unsigned int *read_bytes, unsigned int len) {
-       unsigned int tmp_before_read_bytes = *read_bytes;
-       unsigned int before_read_bytes = 0;
-
+static int parse_lf_class(SLF_CLASS *lf_class, const ut8 *leaf_data, ut32 *read_bytes, ut32 len) {
+       const ut32 start = *read_bytes;
+       const ut32 fixed_size = 16;
+       if (!can_read (*read_bytes, fixed_size, len)) {
+               return 0;
+       }
        lf_class->size.name_or_val = 0;
-
-       READ2 (*read_bytes, len, lf_class->count, leaf_data, ut16);
-       READ2 (*read_bytes, len, lf_class->prop.cv_property, leaf_data, ut16);
-       READ4 (*read_bytes, len, lf_class->field_list, leaf_data, ut32);
-       READ4 (*read_bytes, len, lf_class->derived, leaf_data, ut32);
-       READ4 (*read_bytes, len, lf_class->vshape, leaf_data, ut32);
-
-       before_read_bytes = *read_bytes;
-       parse_sval (&lf_class->size, leaf_data, read_bytes, len);
-       before_read_bytes = *read_bytes - before_read_bytes;
-       leaf_data = (uint8_t *)leaf_data + before_read_bytes;
-
-       PEEK_READ1 (*read_bytes, len, lf_class->pad, leaf_data, ut8);
-       PAD_ALIGN (lf_class->pad, *read_bytes, leaf_data, len);
-
-       return *read_bytes - tmp_before_read_bytes;
+       lf_class->count = r_read_le16 (leaf_data);
+       lf_class->prop.cv_property = r_read_le16 (leaf_data + 2);
+       lf_class->field_list = r_read_le32 (leaf_data + 4);
+       lf_class->derived = r_read_le32 (leaf_data + 8);
+       lf_class->vshape = r_read_le32 (leaf_data + 12);
+       leaf_data += fixed_size;
+       *read_bytes += fixed_size;
+       ut32 before = *read_bytes;
+       parse_sval (&lf_class->size, (ut8 *)leaf_data, read_bytes, len);
+       leaf_data += *read_bytes - before;
+       lf_class->pad = (len > *read_bytes)? leaf_data[0]: 0;
+       if (!pad_align (lf_class->pad, (ut8 **)&leaf_data, read_bytes, len)) {
+               return 0;
+       }
+       return *read_bytes - start;
 }
 
-///////////////////////////////////////////////////////////////////////////////
-static int parse_lf_structure(SLF_STRUCTURE *lf_structure, uint8_t *leaf_data, unsigned int *read_bytes, unsigned int len) {
-       //      SLF_STRUCTURE lf_structure;
-       unsigned int tmp_before_read_bytes = *read_bytes;
-       unsigned int before_read_bytes = 0;
-
+static int parse_lf_structure(SLF_STRUCTURE *lf_structure, const ut8 *leaf_data, ut32 *read_bytes, ut32 len) {
+       const ut32 start = *read_bytes;
+       const ut32 fixed_size = 16;
+       if (!can_read (*read_bytes, fixed_size, len)) {
+               return 0;
+       }
        lf_structure->size.name_or_val = 0;
-       READ2 (*read_bytes, len, lf_structure->count, leaf_data, ut16);
-       READ2 (*read_bytes, len, lf_structure->prop.cv_property, leaf_data, ut16);
-       READ4 (*read_bytes, len, lf_structure->field_list, leaf_data, ut32);
-       READ4 (*read_bytes, len, lf_structure->derived, leaf_data, ut32);
-       READ4 (*read_bytes, len, lf_structure->vshape, leaf_data, ut32);
-       // Why flipping?? Works just right without it
-       // lf_structure->prop.cv_property = SWAP_UINT16 (lf_structure->prop.cv_property);
-
-       before_read_bytes = *read_bytes;
-       parse_sval (&lf_structure->size, leaf_data, read_bytes, len);
-       leaf_data += (*read_bytes - before_read_bytes);
-
-       PEEK_READ1 (*read_bytes, len, lf_structure->pad, leaf_data, ut8);
-       PAD_ALIGN (lf_structure->pad, *read_bytes, leaf_data, len);
-
-       return *read_bytes - tmp_before_read_bytes;
+       lf_structure->count = r_read_le16 (leaf_data);
+       lf_structure->prop.cv_property = r_read_le16 (leaf_data + 2);
+       lf_structure->field_list = r_read_le32 (leaf_data + 4);
+       lf_structure->derived = r_read_le32 (leaf_data + 8);
+       lf_structure->vshape = r_read_le32 (leaf_data + 12);
+       leaf_data += fixed_size;
+       *read_bytes += fixed_size;
+       ut32 before = *read_bytes;
+       parse_sval (&lf_structure->size, (ut8 *)leaf_data, read_bytes, len);
+       leaf_data += (*read_bytes - before);
+       lf_structure->pad = (len > *read_bytes)? leaf_data[0]: 0;
+       if (!pad_align (lf_structure->pad, (ut8 **)&leaf_data, read_bytes, len)) {
+               return 0;
+       }
+       return *read_bytes - start;
 }
 
-///////////////////////////////////////////////////////////////////////////////
-static int parse_lf_pointer(SLF_POINTER *lf_pointer, uint8_t *leaf_data, unsigned int *read_bytes, unsigned int len) {
-       unsigned int tmp_before_read_bytes = *read_bytes;
-
-       READ4 (*read_bytes, len, lf_pointer->utype, leaf_data, ut32);
-       READ4 (*read_bytes, len, lf_pointer->ptr_attr.ptr_attr, leaf_data, ut32);
-
-       // lf_pointer->ptr_attr.ptr_attr = SWAP_UINT32 (lf_pointer->ptr_attr.ptr_attr);
-
-       PEEK_READ1 (*read_bytes, len, lf_pointer->pad, leaf_data, ut8);
-       PAD_ALIGN (lf_pointer->pad, *read_bytes, leaf_data, len);
-
-       return *read_bytes - tmp_before_read_bytes;
+static int parse_lf_pointer(SLF_POINTER *lf_pointer, const ut8 *leaf_data, ut32 *read_bytes, ut32 len) {
+       const ut32 start = *read_bytes;
+       const ut32 fixed_size = 8;
+       if (!can_read (*read_bytes, fixed_size, len)) {
+               return 0;
+       }
+       lf_pointer->utype = r_read_le32 (leaf_data);
+       lf_pointer->ptr_attr.ptr_attr = r_read_le32 (leaf_data + 4);
+       leaf_data += fixed_size;
+       *read_bytes += fixed_size;
+       lf_pointer->pad = (len > *read_bytes)? leaf_data[0]: 0;
+       if (!pad_align (lf_pointer->pad, (ut8 **)&leaf_data, read_bytes, len)) {
+               return 0;
+       }
+       return *read_bytes - start;
 }
 
-///////////////////////////////////////////////////////////////////////////////
-static int parse_lf_array(SLF_ARRAY *lf_array, uint8_t *leaf_data, unsigned int *read_bytes, unsigned int len) {
-       unsigned int tmp_before_read_bytes = *read_bytes;
-       unsigned int before_read_bytes = 0;
-
+static int parse_lf_array(SLF_ARRAY *lf_array, const ut8 *leaf_data, ut32 *read_bytes, ut32 len) {
+       const ut32 start = *read_bytes;
+       const ut32 fixed_size = 8;
+       if (!can_read (*read_bytes, fixed_size, len)) {
+               return 0;
+       }
        lf_array->size.name_or_val = 0;
-
-       READ4 (*read_bytes, len, lf_array->element_type, leaf_data, ut32);
-       READ4 (*read_bytes, len, lf_array->index_type, leaf_data, ut32);
-
-       before_read_bytes = *read_bytes;
-       parse_sval (&lf_array->size, leaf_data, read_bytes, len);
-       leaf_data += (*read_bytes - before_read_bytes);
-
-       PEEK_READ1 (*read_bytes, len, lf_array->pad, leaf_data, ut8);
-       PAD_ALIGN (lf_array->pad, *read_bytes, leaf_data, len);
-
-       return *read_bytes - tmp_before_read_bytes;
+       lf_array->element_type = r_read_le32 (leaf_data);
+       lf_array->index_type = r_read_le32 (leaf_data + 4);
+       leaf_data += fixed_size;
+       *read_bytes += fixed_size;
+       ut32 before = *read_bytes;
+       parse_sval (&lf_array->size, (ut8 *)leaf_data, read_bytes, len);
+       leaf_data += (*read_bytes - before);
+       lf_array->pad = (len > *read_bytes)? leaf_data[0]: 0;
+       if (!pad_align (lf_array->pad, (ut8 **)&leaf_data, read_bytes, len)) {
+               return 0;
+       }
+       return *read_bytes - start;
 }
 
-///////////////////////////////////////////////////////////////////////////////
-static int parse_lf_modifier(SLF_MODIFIER *lf_modifier, uint8_t *leaf_data, unsigned int *read_bytes, unsigned int len) {
-       unsigned int tmp_before_read_bytes = *read_bytes;
-
-       READ4 (*read_bytes, len, lf_modifier->modified_type, leaf_data, ut32);
-       READ2 (*read_bytes, len, lf_modifier->umodifier.modifier, leaf_data, ut16);
-
-       // what is the reason for the swap vs modifying the bitfield so it is correct
-       // lf_modifier->umodifier.modifier = SWAP_UINT16 (lf_modifier->umodifier.modifier);
-
-       PEEK_READ1 (*read_bytes, len, lf_modifier->pad, leaf_data, ut8);
-       PAD_ALIGN (lf_modifier->pad, *read_bytes, leaf_data, len);
-
-       return *read_bytes - tmp_before_read_bytes;
+static int parse_lf_modifier(SLF_MODIFIER *lf_modifier, const ut8 *leaf_data, ut32 *read_bytes, ut32 len) {
+       const ut32 start = *read_bytes;
+       const ut32 fixed_size = 6;
+       if (!can_read (*read_bytes, fixed_size, len)) {
+               return 0;
+       }
+       lf_modifier->modified_type = r_read_le32 (leaf_data);
+       lf_modifier->umodifier.modifier = r_read_le16 (leaf_data + 4);
+       leaf_data += fixed_size;
+       *read_bytes += fixed_size;
+       lf_modifier->pad = (len > *read_bytes)? leaf_data[0]: 0;
+       if (!pad_align (lf_modifier->pad, (ut8 **)&leaf_data, read_bytes, len)) {
+               return 0;
+       }
+       return *read_bytes - start;
 }
 
-///////////////////////////////////////////////////////////////////////////////
-static int parse_lf_arglist(SLF_ARGLIST *lf_arglist, uint8_t *leaf_data, unsigned int *read_bytes, unsigned int len) {
-       unsigned int tmp_before_read_bytes = *read_bytes;
-
+static int parse_lf_arglist(SLF_ARGLIST *lf_arglist, const ut8 *leaf_data, ut32 *read_bytes, ut32 len) {
+       const ut32 start = *read_bytes;
+       if (!can_read (*read_bytes, 4, len)) {
+               return 0;
+       }
        lf_arglist->arg_type = 0;
-
-       READ4 (*read_bytes, len, lf_arglist->count, leaf_data, ut32);
-
-       lf_arglist->arg_type = (unsigned int *)malloc (lf_arglist->count * 4);
+       lf_arglist->count = r_read_le32 (leaf_data);
+       leaf_data += 4;
+       *read_bytes += 4;
+       if (!can_read_array (*read_bytes, lf_arglist->count, 4, len)) {
+               return 0;
+       }
+       const ut32 byte_size = lf_arglist->count * 4;
+       lf_arglist->arg_type = (unsigned int *)malloc (byte_size);
        if (!lf_arglist->arg_type) {
                return 0;
        }
-       memcpy (lf_arglist->arg_type, leaf_data, lf_arglist->count * 4);
-       leaf_data += (lf_arglist->count * 4);
-       *read_bytes += (lf_arglist->count * 4);
-
-       PEEK_READ1 (*read_bytes, len, lf_arglist->pad, leaf_data, ut8);
-       PAD_ALIGN (lf_arglist->pad, *read_bytes, leaf_data, len);
-
-       return *read_bytes - tmp_before_read_bytes;
+       memcpy (lf_arglist->arg_type, leaf_data, byte_size);
+       leaf_data += byte_size;
+       *read_bytes += byte_size;
+       lf_arglist->pad = (len > *read_bytes)? leaf_data[0]: 0;
+       if (!pad_align (lf_arglist->pad, (ut8 **)&leaf_data, read_bytes, len)) {
+               return 0;
+       }
+       return *read_bytes - start;
 }
 
-///////////////////////////////////////////////////////////////////////////////
-static int parse_lf_mfunction(SLF_MFUNCTION *lf_mfunction, uint8_t *leaf_data, unsigned int *read_bytes, unsigned int len) {
-       unsigned int tmp_before_read_bytes = *read_bytes;
-
-       READ4 (*read_bytes, len, lf_mfunction->return_type, leaf_data, ut32);
-       READ4 (*read_bytes, len, lf_mfunction->class_type, leaf_data, ut32);
-       READ4 (*read_bytes, len, lf_mfunction->this_type, leaf_data, ut32);
-       READ1 (*read_bytes, len, lf_mfunction->call_conv, leaf_data, ut8);
-       READ1 (*read_bytes, len, lf_mfunction->reserved, leaf_data, ut8);
-       READ2 (*read_bytes, len, lf_mfunction->parm_count, leaf_data, ut8);
-       READ4 (*read_bytes, len, lf_mfunction->arglist, leaf_data, ut32);
-       READ4 (*read_bytes, len, lf_mfunction->this_adjust, leaf_data, st32);
-
-       PEEK_READ1 (*read_bytes, len, lf_mfunction->pad, leaf_data, ut8);
-       PAD_ALIGN (lf_mfunction->pad, *read_bytes, leaf_data, len);
-
-       return *read_bytes - tmp_before_read_bytes;
+static int parse_lf_mfunction(SLF_MFUNCTION *lf_mfunction, const ut8 *leaf_data, ut32 *read_bytes, ut32 len) {
+       const ut32 start = *read_bytes;
+       const ut32 fixed_size = 24;
+       if (!can_read (*read_bytes, fixed_size, len)) {
+               return 0;
+       }
+       lf_mfunction->return_type = r_read_le32 (leaf_data);
+       lf_mfunction->class_type = r_read_le32 (leaf_data + 4);
+       lf_mfunction->this_type = r_read_le32 (leaf_data + 8);
+       lf_mfunction->call_conv = leaf_data[12];
+       lf_mfunction->reserved = leaf_data[13];
+       lf_mfunction->parm_count = r_read_le16 (leaf_data + 14);
+       lf_mfunction->arglist = r_read_le32 (leaf_data + 16);
+       lf_mfunction->this_adjust = (st32)r_read_le32 (leaf_data + 20);
+       leaf_data += fixed_size;
+       *read_bytes += fixed_size;
+       lf_mfunction->pad = (len > *read_bytes)? leaf_data[0]: 0;
+       if (!pad_align (lf_mfunction->pad, (ut8 **)&leaf_data, read_bytes, len)) {
+               return 0;
+       }
+       return *read_bytes - start;
 }
 
-static int parse_lf_procedure(SLF_PROCEDURE *lf_procedure, uint8_t *leaf_data, unsigned int *read_bytes, unsigned int len) {
-       unsigned int tmp_before_read_bytes = *read_bytes;
-
-       READ4 (*read_bytes, len, lf_procedure->return_type, leaf_data, ut32);
-       READ1 (*read_bytes, len, lf_procedure->call_conv, leaf_data, ut8);
-       READ1 (*read_bytes, len, lf_procedure->reserved, leaf_data, ut8);
-       READ2 (*read_bytes, len, lf_procedure->parm_count, leaf_data, ut16);
-       READ4 (*read_bytes, len, lf_procedure->arg_list, leaf_data, ut32);
-
-       PEEK_READ1 (*read_bytes, len, lf_procedure->pad, leaf_data, ut8);
-       PAD_ALIGN (lf_procedure->pad, *read_bytes, leaf_data, len);
-
-       return *read_bytes - tmp_before_read_bytes;
+static int parse_lf_procedure(SLF_PROCEDURE *lf_procedure, const ut8 *leaf_data, ut32 *read_bytes, ut32 len) {
+       const ut32 start = *read_bytes;
+       const ut32 fixed_size = 12;
+       if (!can_read (*read_bytes, fixed_size, len)) {
+               return 0;
+       }
+       lf_procedure->return_type = (ut16)r_read_le32 (leaf_data);
+       lf_procedure->call_conv = leaf_data[4];
+       lf_procedure->reserved = leaf_data[5];
+       lf_procedure->parm_count = r_read_le16 (leaf_data + 6);
+       lf_procedure->arg_list = r_read_le32 (leaf_data + 8);
+       leaf_data += fixed_size;
+       *read_bytes += fixed_size;
+       lf_procedure->pad = (len > *read_bytes)? leaf_data[0]: 0;
+       if (!pad_align (lf_procedure->pad, (ut8 **)&leaf_data, read_bytes, len)) {
+               return 0;
+       }
+       return *read_bytes - start;
 }
 
-static int parse_lf_union(SLF_UNION *lf_union, uint8_t *leaf_data, unsigned int *read_bytes, unsigned int len) {
-       unsigned int tmp_before_read_bytes = *read_bytes;
-       unsigned int before_read_bytes = 0;
-
+static int parse_lf_union(SLF_UNION *lf_union, const ut8 *leaf_data, ut32 *read_bytes, ut32 len) {
+       const ut32 start = *read_bytes;
+       const ut32 fixed_size = 8;
+       if (!can_read (*read_bytes, fixed_size, len)) {
+               return 0;
+       }
        lf_union->size.name_or_val = 0;
-
-       READ2 (*read_bytes, len, lf_union->count, leaf_data, ut16);
-       READ2 (*read_bytes, len, lf_union->prop.cv_property, leaf_data, ut16);
-       READ4 (*read_bytes, len, lf_union->field_list, leaf_data, ut32);
-
-       before_read_bytes = *read_bytes;
-       parse_sval (&lf_union->size, leaf_data, read_bytes, len);
-       before_read_bytes = *read_bytes - before_read_bytes;
-       leaf_data = (uint8_t *)leaf_data + before_read_bytes;
-
-       PEEK_READ1 (*read_bytes, len, lf_union->pad, leaf_data, ut8);
-       PAD_ALIGN (lf_union->pad, *read_bytes, leaf_data, len);
-
-       return *read_bytes - tmp_before_read_bytes;
+       lf_union->count = r_read_le16 (leaf_data);
+       lf_union->prop.cv_property = r_read_le16 (leaf_data + 2);
+       lf_union->field_list = r_read_le32 (leaf_data + 4);
+       leaf_data += fixed_size;
+       *read_bytes += fixed_size;
+       ut32 before = *read_bytes;
+       parse_sval (&lf_union->size, (ut8 *)leaf_data, read_bytes, len);
+       leaf_data += *read_bytes - before;
+       lf_union->pad = (len > *read_bytes)? leaf_data[0]: 0;
+       if (!pad_align (lf_union->pad, (ut8 **)&leaf_data, read_bytes, len)) {
+               return 0;
+       }
+       return *read_bytes - start;
 }
 
-static int parse_lf_bitfield(SLF_BITFIELD *lf_bitfield, uint8_t *leaf_data, unsigned int *read_bytes, unsigned int len) {
-       unsigned int tmp_before_read_bytes = *read_bytes;
-
-       READ4 (*read_bytes, len, lf_bitfield->base_type, leaf_data, ut32);
-       READ1 (*read_bytes, len, lf_bitfield->length, leaf_data, ut8);
-       READ1 (*read_bytes, len, lf_bitfield->position, leaf_data, ut8);
-
-       PEEK_READ1 (*read_bytes, len, lf_bitfield->pad, leaf_data, ut8);
-       PAD_ALIGN (lf_bitfield->pad, *read_bytes, leaf_data, len);
-
-       return *read_bytes - tmp_before_read_bytes;
+static int parse_lf_bitfield(SLF_BITFIELD *lf_bitfield, const ut8 *leaf_data, ut32 *read_bytes, ut32 len) {
+       const ut32 start = *read_bytes;
+       const ut32 fixed_size = 6;
+       if (!can_read (*read_bytes, fixed_size, len)) {
+               return 0;
+       }
+       lf_bitfield->base_type = r_read_le32 (leaf_data);
+       lf_bitfield->length = leaf_data[4];
+       lf_bitfield->position = leaf_data[5];
+       leaf_data += fixed_size;
+       *read_bytes += fixed_size;
+       lf_bitfield->pad = (len > *read_bytes)? leaf_data[0]: 0;
+       if (!pad_align (lf_bitfield->pad, (ut8 **)&leaf_data, read_bytes, len)) {
+               return 0;
+       }
+       return *read_bytes - start;
 }
 
-static int parse_lf_vtshape(SLF_VTSHAPE *lf_vtshape, uint8_t *leaf_data, unsigned int *read_bytes, unsigned int len) {
-       unsigned int tmp_before_read_bytes = *read_bytes;
-       unsigned int size; // in bytes;
-
+static int parse_lf_vtshape(SLF_VTSHAPE *lf_vtshape, const ut8 *leaf_data, ut32 *read_bytes, ut32 len) {
+       const ut32 start = *read_bytes;
+       if (!can_read (*read_bytes, 2, len)) {
+               return 0;
+       }
        lf_vtshape->vt_descriptors = 0;
-
-       READ2 (*read_bytes, len, lf_vtshape->count, leaf_data, ut16);
-
-       size = (4 * lf_vtshape->count + (lf_vtshape->count % 2) * 4) / 8;
+       lf_vtshape->count = r_read_le16 (leaf_data);
+       leaf_data += 2;
+       *read_bytes += 2;
+       const ut32 size = (4 * lf_vtshape->count + (lf_vtshape->count % 2) * 4) / 8;
+       if (!can_read (*read_bytes, size, len)) {
+               return 0;
+       }
        lf_vtshape->vt_descriptors = (char *)malloc (size);
        if (!lf_vtshape->vt_descriptors) {
                return 0;
@@ -2611,11 +2584,11 @@ static int parse_lf_vtshape(SLF_VTSHAPE *lf_vtshape, uint8_t *leaf_data, unsigne
        memcpy (lf_vtshape->vt_descriptors, leaf_data, size);
        leaf_data += size;
        *read_bytes += size;
-
-       PEEK_READ1 (*read_bytes, len, lf_vtshape->pad, leaf_data, ut8);
-       PAD_ALIGN (lf_vtshape->pad, *read_bytes, leaf_data, len);
-
-       return *read_bytes - tmp_before_read_bytes;
+       lf_vtshape->pad = (len > *read_bytes)? leaf_data[0]: 0;
+       if (!pad_align (lf_vtshape->pad, (ut8 **)&leaf_data, read_bytes, len)) {
+               return 0;
+       }
+       return *read_bytes - start;
 }
 
 #define PARSE_LF(lf_type, lf_func) \
@@ -2662,6 +2635,7 @@ static int parse_tpi_stypes(R_STREAM_FILE *stream, SType *type) {
                break;
        case eLF_POINTER:
                {
+                       // PARSE_LF (SLF_POINTER, lf_pointer);
                        SLF_POINTER *lf = (SLF_POINTER *)malloc (sizeof (SLF_POINTER));
                        if (!lf) {
                                free (leaf_data);
@@ -2671,8 +2645,7 @@ static int parse_tpi_stypes(R_STREAM_FILE *stream, SType *type) {
                        type->type_data.type_info = (void *)lf;
                        init_stype_info (&type->type_data);
                }
-       //              PARSE_LF (SLF_POINTER, lf_pointer);
-       break;
+               break;
        case eLF_ARRAY:
                PARSE_LF (SLF_ARRAY, lf_array);
                break;
@@ -2711,33 +2684,29 @@ static int parse_tpi_stypes(R_STREAM_FILE *stream, SType *type) {
        return read_bytes;
 }
 
-int parse_tpi_stream(STpiStream *ss, R_STREAM_FILE *stream) {
-       int i, ret = 1;
-
+// XXX this function never return false.. which is probably incorrect. needs review
+bool parse_tpi_stream(STpiStream *ss, R_STREAM_FILE *stream) {
        ss->types = r_list_new ();
-       if (!ss->types) {
-               return 0;
-       }
-
        // Initialize context for parsing session
        stream_file_read (stream, sizeof (STPIHeader), (char *)&ss->header);
 
        ss->ctx.base_idx = ss->header.idx_begin;
        ss->ctx.types_list = ss->types;
 
+       int i;
        for (i = ss->header.idx_begin; i < ss->header.idx_end; i++) {
                SType *type = R_NEW0 (SType);
                type->tpi_idx = i;
                type->type_data.type_info = 0;
                type->type_data.leaf_type = eLF_MAX;
                init_stype_info (&type->type_data);
-               if (!parse_tpi_stypes (stream, type)) {
-                       R_FREE (type);
+               if (parse_tpi_stypes (stream, type)) {
+                       r_list_append (ss->types, type);
+               } else {
+                       free (type);
                }
-               r_list_append (ss->types, type);
        }
-
-       return ret;
+       return true;
 }
 
 void init_tpi_stream(STpiStream *ss) {
index 4d80bfab9262815464910e9ca43b569f5284be5e..e02361c7be8a11f992e5777eb409af99142c3ad5 100644 (file)
@@ -1,18 +1,11 @@
 #ifndef TPI_H
 #define TPI_H
 
-///////////////////////////////////////////////////////////////////////////////
 void init_tpi_stream(STpiStream *tpi_stream);
-
-///////////////////////////////////////////////////////////////////////////////
-int parse_tpi_stream(STpiStream *ss, R_STREAM_FILE *stream);
-
+bool parse_tpi_stream(STpiStream *ss, R_STREAM_FILE *stream);
 // TODO: Remove to separate file
-int parse_sctring(SCString *sctr, unsigned char *leaf_data, unsigned int *read_bytes, unsigned int len);
-
-// use r2 types here (ut16 instead of unsigned short, ut32 for unsigned int ..)
-///////////////////////////////////////////////////////////////////////////////
-void init_scstring(SCString *cstr, unsigned int size, char *name);
+int parse_sctring(SCString *sctr, ut8 *leaf_data, ut32 *read_bytes, ut32 len);
+void init_scstring(SCString *cstr, ut32 size, char *name);
 
 // Free a dynamically allocated simple type (tpi_idx == 0)
 static inline void tpi_free_simple_type(SType *t) {
index 475bc41f1095dc6ff33743c93f888e5e17e30f2a..f501d18713a6c75e062a99de4186811c9f31a03b 100644 (file)
@@ -6,8 +6,6 @@
 
 #define READ_PAGE_FAIL 0x01
 
-// TODO: Move to a general macros in r_util/r_types
-
 ///////////////////////////////////////////////////////////////////////////////
 #define GET_PAGE(pn, off, pos, page_size)      { \
        (pn) = (pos) / (page_size); \
 ///////////////////////////////////////////////////////////////////////////////
 #define SWAP_UINT16(x) (((x) >> 8) | ((x) << 8))
 
-///////////////////////////////////////////////////////////////////////////////
-#define SWAP_UINT32(x) (((x) >> 24) | (((x) & 0x00FF0000) >> 8) | (((x) & 0x0000FF00) << 8) | ((x) << 24))
-
-///////////////////////////////////////////////////////////////////////////////
-#define CAN_READ(curr_read_bytes, bytes_for_read, max_len) { \
-       if ((((curr_read_bytes) + (bytes_for_read)) > (max_len))) { \
-               return 0; \
-       } \
-}
-
-///////////////////////////////////////////////////////////////////////////////
-#define UPDATE_DATA(src, curr_read_bytes, bytes_for_read) { \
-       (src) += (bytes_for_read); \
-       (curr_read_bytes) += (bytes_for_read); \
-}
-
-///////////////////////////////////////////////////////////////////////////////
-#define PEEK_READ1(curr_read_bytes, max_len, dst, src, type_name) { \
-       CAN_READ((curr_read_bytes), 1, (max_len)); \
-       (dst) = *(type_name *) (src); \
-}
-#define PEEK_READ2(curr_read_bytes, max_len, dst, src, type_name) { \
-       CAN_READ((curr_read_bytes), 2, (max_len)); \
-       (dst) = (type_name) r_read_le16 (src); \
-}
-#define PEEK_READ4(curr_read_bytes, max_len, dst, src, type_name) { \
-       CAN_READ((curr_read_bytes), 4, (max_len)); \
-       (dst) = (type_name) r_read_le32 (src); \
-}
-#define PEEK_READ8(curr_read_bytes, max_len, dst, src, type_name) { \
-       CAN_READ((curr_read_bytes), 8, (max_len)); \
-       (dst) = (type_name) r_read_le64 (src); \
-}
-///////////////////////////////////////////////////////////////////////////////
-#define READ1(curr_read_bytes, max_len, dst, src, type_name) { \
-       PEEK_READ1((curr_read_bytes), (max_len), (dst), (src), type_name); \
-       UPDATE_DATA((src), (curr_read_bytes), 1); \
-}
-
-#define READ2(curr_read_bytes, max_len, dst, src, type_name) { \
-       PEEK_READ2((curr_read_bytes), (max_len), (dst), (src), type_name); \
-       UPDATE_DATA((src), (curr_read_bytes), 2); \
-}
-
-#define READ4(curr_read_bytes, max_len, dst, src, type_name) { \
-       PEEK_READ4((curr_read_bytes), (max_len), (dst), (src), type_name); \
-       UPDATE_DATA((src), (curr_read_bytes), 4); \
+static inline bool can_read(ut32 pos, ut32 n, ut32 len) {
+       return pos <= len && n <= len - pos;
 }
 
-#define READ8(curr_read_bytes, max_len, dst, src, type_name) { \
-       PEEK_READ8((curr_read_bytes), (max_len), (dst), (src), type_name); \
-       UPDATE_DATA((src), (curr_read_bytes), 8); \
+static inline bool can_read_array(ut32 pos, ut32 count, ut32 elem_size, ut32 len) {
+       return pos <= len && count <= (len - pos) / elem_size;
 }
 
-///////////////////////////////////////////////////////////////////////////////
-#define PAD_ALIGN(pad, curr_read_bytes, src, max_len) { \
-       int tmp = 0; \
-       if ((pad) > 0xF0) { \
-               tmp = (pad) & 0x0F; \
-               CAN_READ((curr_read_bytes), (tmp), (len)); \
-               UPDATE_DATA((src), (curr_read_bytes), (tmp)); \
-       } \
+static inline bool pad_align(ut8 pad, ut8 **src, ut32 *pos, ut32 len) {
+       if (pad > 0xF0) {
+               const ut32 skip = pad & 0x0F;
+               if (!can_read (*pos, skip, len)) {
+                       return false;
+               }
+               *src += skip;
+               *pos += skip;
+       }
+       return true;
 }
 
 typedef struct R_STREAM_FILE_{
index b8159729e07836122a265860e253198a8e128f9e..0ab924b4475358fe612445382679a85a34853491 100644 (file)
@@ -545,7 +545,7 @@ R_API st64 r_hex_bin_truncate(ut64 in, int n) {
        return in;
 }
 
-// Check if str contains only hexadecimal characters and return length of bytes
+// Check if str contains only hexadecimal characters and return length of bytes or -1
 R_API int r_hex_str_is_valid(const char* str) {
        R_RETURN_VAL_IF_FAIL (str, -1);
        int i, len = 0;