Skip to content

Commit fdab4b9

Browse files
committed
Found the reason why the naive search sometimes fails and fixed it.
Now the (in a zipfile potentially very slow) "proper" search should really never be necessary, but keep it, just in case. Maybe there will be even more of those alterations of the real name.
1 parent a254b2c commit fdab4b9

File tree

1 file changed

+34
-14
lines changed

1 file changed

+34
-14
lines changed

lib/inputstreamhelper/widevine/arm_chromeos.py

Lines changed: 34 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -73,34 +73,54 @@ def chromeos_offset(self):
7373

7474
return offset
7575

76-
def _find_file_naive(self, filename):
76+
def _find_file_in_chunk(self, bfname, chunk):
77+
"""
78+
Checks if the filename is found in the given chunk.
79+
Then makes some plausibility checks, to see if it is in fact a proper dentry.
80+
81+
returns the dentry if found, else False.
82+
"""
83+
84+
if bfname in chunk:
85+
i_index_pos = chunk.index(bfname) - 8 # the filename is the last element of the dentry, the elements before are 8 bytes total
86+
file_entry = self.dir_entry(chunk[i_index_pos:i_index_pos + len(bfname) + 8]) # 8 because see above
87+
if file_entry['inode'] < self.sb_dict['s_inodes_count'] and file_entry['name_len'] == len(bfname):
88+
return file_entry
89+
90+
log(0, 'Found filename, but checks did not pass:')
91+
log(0, 'inode number: {inode} < {count}, name_len: {name_len} == {len_fname}'.format(inode=file_entry['inode'],
92+
count=self.sb_dict['s_inodes_count'],
93+
name_len=file_entry['name_len'],
94+
len_fname=len(bfname)))
95+
return False
96+
97+
def _find_file_naive(self, fname):
7798
"""
7899
Finds a file by basically searching for the filename as bytes in the bytestream.
79100
Searches through the whole image only once, making it fast, but may be unreliable at times.
80101
81102
Returns a directory entry.
82103
"""
83104

84-
bin_filename = filename.encode('ascii')
105+
fname_alt = fname + '#new' # Sometimes the filename has "#new" at the end
106+
bfname = fname.encode('ascii')
107+
bfname_alt = fname_alt.encode('ascii')
85108
chunksize = 4 * 1024**2
86109
chunk1 = self.read_stream(chunksize)
87110
while True:
88111
chunk2 = self.read_stream(chunksize)
89112
if not chunk2:
90-
raise ChromeOSError('File {filename} not found in the ChromeOS image'.format(filename=filename))
113+
raise ChromeOSError('File {fname} not found in the ChromeOS image'.format(fname=fname))
91114

92115
chunk = chunk1 + chunk2
93-
if bin_filename in chunk:
94-
i_index_pos = chunk.index(bin_filename) - 8
95-
file_entry = self.dir_entry(chunk[i_index_pos:i_index_pos + len(filename) + 8])
96-
if file_entry['inode'] < self.sb_dict['s_inodes_count'] and file_entry['name_len'] == len(filename):
97-
break
98-
99-
log(0, 'Found filename, but checks did not pass:')
100-
log(0, 'inode number: {inode} < {count}, name_len: {name_len} == {len_filename}'.format(inode=file_entry['inode'],
101-
count=self.sb_dict['s_inodes_count'],
102-
name_len=file_entry['name_len'],
103-
len_filename=len(filename)))
116+
117+
file_entry = self._find_file_in_chunk(bfname, chunk)
118+
if file_entry:
119+
break
120+
121+
file_entry = self._find_file_in_chunk(bfname_alt, chunk)
122+
if file_entry:
123+
break
104124

105125
chunk1 = chunk2
106126

0 commit comments

Comments
 (0)