예제 #1
0
    def extract_entry(self, e, decompress='auto'):
        """Yield blocks of data for this entry from this MAR file.

        Args:
            e (:obj:`mardor.format.index_entry`): An index_entry object that
                refers to this file's size and offset inside the MAR file.
            path (str): Where on disk to extract this file to.
            decompress (str, optional): Controls whether files are decompressed
                when extracted. Must be one of None, 'auto', 'bz2', or 'xz'.
                Defaults to 'auto'

        Yields:
            Blocks of data for `e`
        """
        self.fileobj.seek(e.offset)
        stream = file_iter(self.fileobj)
        stream = takeexactly(stream, e.size)
        if decompress == 'auto':
            stream = auto_decompress_stream(stream)
        elif decompress == 'bz2':
            stream = bz2_decompress_stream(stream)
        elif decompress == 'xz':
            stream = xz_decompress_stream(stream)
        elif decompress is None:
            pass
        else:
            raise ValueError("Unsupported decompression type: {}".format(decompress))

        for block in stream:
            yield block
예제 #2
0
파일: reader.py 프로젝트: mozilla/build-mar
    def extract_entry(self, e, decompress='auto'):
        """Yield blocks of data for this entry from this MAR file.

        Args:
            e (:obj:`mardor.format.index_entry`): An index_entry object that
                refers to this file's size and offset inside the MAR file.
            path (str): Where on disk to extract this file to.
            decompress (str, optional): Controls whether files are decompressed
                when extracted. Must be one of None, 'auto', 'bz2', or 'xz'.
                Defaults to 'auto'

        Yields:
            Blocks of data for `e`

        """
        self.fileobj.seek(e.offset)
        stream = file_iter(self.fileobj)
        stream = takeexactly(stream, e.size)
        if decompress == 'auto':
            stream = auto_decompress_stream(stream)
        elif decompress == 'bz2':
            stream = bz2_decompress_stream(stream)
        elif decompress == 'xz':
            stream = xz_decompress_stream(stream)
        elif decompress is None:
            pass
        else:
            raise ValueError("Unsupported decompression type: {}".format(decompress))

        for block in stream:
            yield block
예제 #3
0
def test_takeexactly_notenough(data):
    n = len(b''.join(data))
    with pytest.raises(ValueError):
        b''.join(takeexactly(data, n + 1))
예제 #4
0
def test_takeexactly_notenough(data, n):
    assume(len(b''.join(data)) < n)

    with pytest.raises(ValueError):
        b''.join(takeexactly(data, n))
예제 #5
0
def test_takeexactly(data):
    n = len(b''.join(data))
    for i in range(n + 1):
        assert len(b''.join(takeexactly(data, i))) == i
예제 #6
0
def test_takeexactly(data, n):
    assume(len(b''.join(data)) >= n)

    assert len(b''.join(takeexactly(data, n))) == n
예제 #7
0
파일: writer.py 프로젝트: mozilla/build-mar
def add_signature_block(src_fileobj, dest_fileobj, signing_algorithm, signature=None):
    """Add a signature block to marfile, a MarReader object.

    Productversion and channel are preserved, but any existing signatures are overwritten.

    Args:
        src_fileobj (file object): The input MAR file to add a signature to
        dest_fileobj (file object): File object to write new MAR file to. Must be open in w+b mode.
        signing_algorithm (str): One of 'sha1', or 'sha384'
        signature (bytes): Signature to write, or None to use a dummy signature
    """
    algo_id = {'sha1': 1, 'sha384': 2}[signing_algorithm]
    if not signature:
        signature = make_dummy_signature(algo_id)

    src_fileobj.seek(0)
    mardata = mar.parse_stream(src_fileobj)

    # Header
    header = mardata.header
    dest_fileobj.write(mar_header.build(header))

    # Signature block
    sig = dict(algorithm_id=algo_id,
               size=len(signature),
               signature=signature,
               )

    # This will be fixed up later
    filesize = 0
    sigs_offset = dest_fileobj.tell()
    sigs = sigs_header.build(dict(
        filesize=filesize,
        count=1,
        sigs=[sig],
    ))
    dest_fileobj.write(sigs)

    # Write the additional section
    dest_fileobj.write(extras_header.build(mardata.additional))

    # Write the data
    data_offset = dest_fileobj.tell()
    src_fileobj.seek(mardata.data_offset)
    write_to_file(takeexactly(src_fileobj, mardata.data_length), dest_fileobj)

    # Write the index
    index_offset = dest_fileobj.tell()

    index = mardata.index

    # Adjust the offsets
    data_offset_delta = data_offset - mardata.data_offset

    for e in index.entries:
        e.offset += data_offset_delta

    dest_fileobj.write(index_header.build(index))
    filesize = dest_fileobj.tell()

    # Go back and update the index offset and filesize
    dest_fileobj.seek(0)
    header.index_offset = index_offset
    dest_fileobj.write(mar_header.build(header))

    dest_fileobj.seek(sigs_offset)
    sigs = sigs_header.build(dict(
        filesize=filesize,
        count=1,
        sigs=[sig],
    ))
    dest_fileobj.write(sigs)
예제 #8
0
def test_takeexactly_notenough(data):
    n = len(b''.join(data))
    with pytest.raises(ValueError):
        b''.join(takeexactly(data, n+1))
예제 #9
0
def test_takeexactly(data):
    n = len(b''.join(data))
    for i in range(n+1):
        assert len(b''.join(takeexactly(data, i))) == i
예제 #10
0
def add_signature_block(src_fileobj,
                        dest_fileobj,
                        signing_algorithm,
                        signature=None):
    """Add a signature block to marfile, a MarReader object.

    Productversion and channel are preserved, but any existing signatures are overwritten.

    Args:
        src_fileobj (file object): The input MAR file to add a signature to
        dest_fileobj (file object): File object to write new MAR file to. Must be open in w+b mode.
        signing_algorithm (str): One of 'sha1', or 'sha384'
        signature (bytes): Signature to write, or None to use a dummy signature
    """
    algo_id = {'sha1': 1, 'sha384': 2}[signing_algorithm]
    if not signature:
        signature = make_dummy_signature(algo_id)

    src_fileobj.seek(0)
    mardata = mar.parse_stream(src_fileobj)

    # Header
    header = mardata.header
    dest_fileobj.write(mar_header.build(header))

    # Signature block
    sig = dict(
        algorithm_id=algo_id,
        size=len(signature),
        signature=signature,
    )

    # This will be fixed up later
    filesize = 0
    sigs_offset = dest_fileobj.tell()
    sigs = sigs_header.build(dict(
        filesize=filesize,
        count=1,
        sigs=[sig],
    ))
    dest_fileobj.write(sigs)

    # Write the additional section
    dest_fileobj.write(extras_header.build(mardata.additional))

    # Write the data
    data_offset = dest_fileobj.tell()
    src_fileobj.seek(mardata.data_offset)
    write_to_file(takeexactly(src_fileobj, mardata.data_length), dest_fileobj)

    # Write the index
    index_offset = dest_fileobj.tell()

    index = mardata.index

    # Adjust the offsets
    data_offset_delta = data_offset - mardata.data_offset

    for e in index.entries:
        e.offset += data_offset_delta

    dest_fileobj.write(index_header.build(index))
    filesize = dest_fileobj.tell()

    # Go back and update the index offset and filesize
    dest_fileobj.seek(0)
    header.index_offset = index_offset
    dest_fileobj.write(mar_header.build(header))

    dest_fileobj.seek(sigs_offset)
    sigs = sigs_header.build(dict(
        filesize=filesize,
        count=1,
        sigs=[sig],
    ))
    dest_fileobj.write(sigs)