2
2
'''
3
3
Parser for ADT string from bap that does not use eval
4
4
5
- The nieve eval-based version runs into out-of-memory conditions on large files
5
+ The naive eval-based version runs into out-of-memory conditions on large files
6
6
'''
7
7
import gc
8
8
import sys
9
9
import time
10
10
11
- # NOTE: uses bap.bir, but cannot import at module level (circular references)
11
+ from subprocess import check_output
12
+
13
+ # bap.1.3 breaks the format of the following types. it prints hexes
14
+ # without prefixing them with the `0x` escape. To fix it without
15
+ # fixing bap, we will treat integers inside this parents as
16
+ # hexadecimals if there is no prefix.
17
+ BROKEN_TYPES = [
18
+ 'Section' ,
19
+ 'Region'
20
+ ]
12
21
22
+ # NOTE: uses bap.bir, but cannot import at module level (circular references)
13
23
14
- def toint (string , start , end ):
24
+ def toint (string , start , end , base = 10 ):
15
25
'''
16
26
Convert substring string[start:end] to integer/long without eval
17
27
18
28
Note: may contain leading whitespace
19
29
'''
20
30
istr = string [start :end ].lstrip ()
21
-
22
31
if sys .version_info > (3 ,): # then longs don't exist
23
32
if istr .endswith ('L' ):
24
33
istr = istr .rstrip ('L' )
@@ -31,7 +40,7 @@ def toint(string, start, end):
31
40
if istr .startswith ('0x' ):
32
41
return of_str (istr , 16 )
33
42
else :
34
- return of_str (istr )
43
+ return of_str (istr , base )
35
44
36
45
def setup_progress (totalitems ):
37
46
'''
@@ -159,17 +168,19 @@ def _parse_end(in_c, in_s, i, objs, stk):
159
168
raise ParserInputError ('Mismatched input stream' )
160
169
j = stk [- 1 ]
161
170
parent = objs [j ]
171
+ ptyp = parent ['typ' ]
162
172
assert isinstance (parent , dict )
163
173
assert parent , 'parent is empty'
164
- assert parent [ 'typ' ] != 'int' , 'parent wrong type: %r' % (parent ['typ' ])
174
+ assert ptyp != 'int' , 'parent wrong type: %r' % (parent ['typ' ])
165
175
assert 'children' in parent
166
176
if top : # add to parent if non empty
167
177
# make real int before appending
168
178
if top ['typ' ] == 'd' : # int
169
179
try :
170
- top = toint (in_s , k , i )
180
+ base = 16 if ptyp in BROKEN_TYPES else 10
181
+ top = toint (in_s , k , i , base )
171
182
except ValueError :
172
- raise ParserInputError ("Integer expected between [%d..%d)" % (top , i ))
183
+ raise ParserInputError ("Integer expected between [%d..%d)" % (k , i ))
173
184
parent ['children' ].append (top )
174
185
if in_c == ',' : # add blank object and move on
175
186
# next obj
@@ -179,7 +190,6 @@ def _parse_end(in_c, in_s, i, objs, stk):
179
190
return i
180
191
else : # we are ending a tuple/list/app do it
181
192
# maybe handle apply (num and seq are earlier)
182
- ptyp = parent ['typ' ]
183
193
if ptyp == '[' :
184
194
if in_c != ']' :
185
195
raise ParserInputError ('close %r and open %r mismatch' % (in_c , ptyp ))
@@ -325,4 +335,3 @@ def parser(input_str, disable_gc=False, logger=None):
325
335
'format' : 'adt' ,
326
336
'load' : parser
327
337
}
328
-
0 commit comments