Exemplo n.º 1
0
 def test_cffolder_add_data(self):
     reserve = {'cbCFHeader': 0, 'cbCFFolder': 0, 'cbCFData': 0}
     cfheader = CFHEADER(flags=0, reserve=reserve)
     cffolder = CFFOLDER(cfheader=cfheader)
     cfdata = CFDATA(data="testdata1")
     cffolder.add_data(cfdata)
     cfdata = CFDATA(data="testdata2")
     cffolder.add_data(cfdata)
     self.assertEquals(2, cffolder.cCFData)
Exemplo n.º 2
0
 def test_cfdata_normal_creation(self):
     data = "this is the data"
     cfdata = CFDATA(data=data)
     self.assertEquals(data, cfdata.ab)
     self.assertEquals(len(data), cfdata.cbData)
     self.assertEquals(len(data), cfdata.cbUncomp)
     self.assertEquals(len(cfdata), len(repr(cfdata)))
Exemplo n.º 3
0
 def test_cfdata_with_reserve(self):
     data = "this is the data"
     reserve = {'cbCFHeader': 0, 'cbCFFolder': 0, 'cbCFData': 20}
     cfheader = CFHEADER(flags=CFHEADER.cfhdrRESERVE_PRESENT,
                         reserve=reserve)
     cffolder = CFFOLDER(cfheader=cfheader)
     cfdata = CFDATA(cffolder=cffolder, data=data)
     self.assertEquals(20, len(cfdata.abReserve))
     self.assertEquals(len(cfdata), len(repr(cfdata)))
Exemplo n.º 4
0
    def add_file(self, folder_name, filename, total_len, data):

        if self.size == self.max_data:
            raise CABException("This cab is full")

        if (self.size + len(data)) <= self.max_data:

            try:
                cffolder = next(_ for _ in self.cffolder_list
                                if _.name == folder_name)
                # We need to check if the cffolder has a cffile scattered that continues from a PREV
                # If this is the case, we need to provide a new cffolder anyways.. this is how it works
                cffolder = self._check_for_scattered_prev_cffile(cffolder)
            except StopIteration:
                cffolder = self._create_cffolder(folder_name)
                self.cffolder_list.append(cffolder)

            cffile = CFFILE(cffolder=cffolder,
                            total_len=total_len,
                            filename=filename)
            self.cffile_list.append(cffile)

            # Max data per CFDATA is 0x8000 -> This is an empirical result
            if len(data) > 0x8000:
                data_chunks = [
                    data[i:i + 0x8000] for i in range(0, len(data), 0x8000)
                ]
                for data_chunk in data_chunks:
                    cfdata = CFDATA(cffolder=cffolder, data=data_chunk)
                    self.cfdata_list.append(cfdata)
                    cffolder.add_data(cfdata)
            else:
                cfdata = CFDATA(cffolder=cffolder, data=data)
                self.cfdata_list.append(cfdata)
                # Update cCFData
                cffolder.add_data(cfdata)

            cffolder.add_file(cffile)

            self.update_fields()
            self.size += len(data)

        else:
            raise CABException("The cab hasn't enough space for the data ")
Exemplo n.º 5
0
 def _read_data_primitive(self, current_cab, cffile):
     file_data = ""
     file_data_len = self.file_data_len
     while file_data_len < cffile.cbFile and self.curr_index_data < len(current_cab.cfdata_list):
         current_cfdata = current_cab.cfdata_list[self.curr_index_data]
         file_data_len += current_cfdata.cbUncomp
         file_data += current_cfdata.ab
         self.curr_index_data += 1
     self.file_data_len = file_data_len
     if self.file_data_len > cffile.cbFile:
         # The CAB compressor of windows does a nasty thing...
         # It allows to share a CFDATA between TWO CFFILES
         # We need to adjust the data if this is the case
         difference = self.file_data_len - cffile.cbFile
         real_file_data = file_data[0:(self.file_data_len-difference)]
         # We will create an anonymous CFDATA and add it to the list ..
         # This way the remaining bytes that belongs to the next CFFILE will be read transparently
         new_cfdata = CFDATA()
         new_cfdata.ab = file_data[(self.file_data_len-difference):self.file_data_len]
         new_cfdata.cbUncomp = len(new_cfdata.ab)
         new_cfdata.cbData = len(new_cfdata.ab)
         current_cab.cfdata_list.insert(self.curr_index_data, new_cfdata)
         return real_file_data
     return file_data
Exemplo n.º 6
0
 def _read_data_primitive(self, current_cab, cffile):
     file_data = ""
     file_data_len = self.file_data_len
     while file_data_len < cffile.cbFile and self.curr_index_data < len(current_cab.cfdata_list):
         current_cfdata = current_cab.cfdata_list[self.curr_index_data]
         file_data_len += current_cfdata.cbUncomp
         file_data += current_cfdata.ab
         self.curr_index_data += 1
     self.file_data_len = file_data_len
     if self.file_data_len > cffile.cbFile:
         # The CAB compressor of windows does a nasty thing...
         # It allows to share a CFDATA between TWO CFFILES
         # We need to adjust the data if this is the case
         difference = self.file_data_len - cffile.cbFile
         real_file_data = file_data[0:(self.file_data_len-difference)]
         # We will create an anonymous CFDATA and add it to the list ..
         # This way the remaining bytes that belongs to the next CFFILE will be read transparently
         new_cfdata = CFDATA()
         new_cfdata.ab = file_data[(self.file_data_len-difference):self.file_data_len]
         new_cfdata.cbUncomp = len(new_cfdata.ab)
         new_cfdata.cbData = len(new_cfdata.ab)
         current_cab.cfdata_list.insert(self.curr_index_data, new_cfdata)
         return real_file_data
     return file_data
Exemplo n.º 7
0
 def read_data(self, handle):
     result = []
     data_count = sum([cffolder.cCFData for cffolder in self.cffolder_list])
     for i in range(data_count):
         parameters = {}
         parameters["csum"] = self._read_dword(handle)
         parameters["cbData"] = self._read_word(handle)
         parameters["cbUncomp"] = self._read_word(handle)
         if self.cfheader.flags & CFHEADER.cfhdrRESERVE_PRESENT:
             parameters["abReserve"] = handle.read(self.cfheader.cbCFData)
         else:
             parameters["abReserve"] = ""
         parameters["ab"] = handle.read(parameters["cbData"])
         result.append(CFDATA.create_from_parameters(parameters=parameters))
     return result