Exemple #1
0
def test_glom_fragmented_file_discontiguous():
    """
    Three out-of-order sectors of the file on disk, f0_f1_f2, are at discontiguous offsets i0, i0+1KiB, i0+1MiB.
    """

    br0 = Objects.ByteRun()
    br1 = Objects.ByteRun()
    br2 = Objects.ByteRun()

    br0.len = 512
    br1.len = 512
    br2.len = 512

    br0.img_offset = 0
    br1.img_offset = br0.img_offset + 2**10
    br2.img_offset = br0.img_offset + 2**20

    br0.file_offset = 0 * 512
    br1.file_offset = 1 * 512
    br2.file_offset = 2 * 512

    br0_br1 = br0 + br1
    br1_br2 = br1 + br2

    try:
        assert br0_br1 is None
    except:
        _logger.debug("br0_br1 = %r." % br0_br1)
        raise

    try:
        assert br1_br2 is None
    except:
        _logger.debug("br1_br2 = %r." % br1_br2)
        raise
Exemple #2
0
def _gen_glom_samples(offset_property="img_offset"):
    """
    Generate three contiguous byte runs.
    """
    br0 = Objects.ByteRun()
    br1 = Objects.ByteRun()
    br2 = Objects.ByteRun()

    br0.len = 20
    br1.len = 30
    br2.len = 10

    if offset_property == "img_offset":
        br0.img_offset = 0
        br1.img_offset = 20
        br2.img_offset = 50
    elif offset_property == "fs_offset":
        br0.fs_offset = 0
        br1.fs_offset = 20
        br2.fs_offset = 50
    elif offset_property == "file_offset":
        br0.file_offset = 0
        br1.file_offset = 20
        br2.file_offset = 50

    return (br0, br1, br2)
Exemple #3
0
def test_glom_fragmented_file_outoforder():
    """
    Three contiguous sectors on disk, i0_i1_i2, contain three out-of-order sectors of the file on disk, f0_f2_f1.
    """

    br0 = Objects.ByteRun()
    br1 = Objects.ByteRun()
    br2 = Objects.ByteRun()

    br0.len = 512
    br1.len = 512
    br2.len = 512

    br0.img_offset = 0 * 512
    br1.img_offset = 1 * 512
    br2.img_offset = 2 * 512

    br0.file_offset = 0 * 512
    br1.file_offset = 2 * 512
    br2.file_offset = 1 * 512

    br0_br1 = br0 + br1
    br1_br2 = br1 + br2

    try:
        assert br0_br1 is None
    except:
        _logger.debug("br0_br1 = %r." % br0_br1)
        raise

    try:
        assert br1_br2 is None
    except:
        _logger.debug("br1_br2 = %r." % br1_br2)
        raise
Exemple #4
0
def test_fill():
    _logger = logging.getLogger(os.path.basename(__file__))
    logging.basicConfig(level=logging.DEBUG)

    br = Objects.ByteRun()
    _logger.debug("br = %r." % br)

    assert br.fill is None

    br.fill = b'\x00'
    _logger.debug("br.fill = %r." % br.fill)
    assert br.fill == b'\x00'

    #Catch current implementation decision.
    multibyte_failed = None
    try:
        br.fill = b'\x00\x01'
    except NotImplementedError as e:
        multibyte_failed = True
    assert multibyte_failed

    br.fill = 0
    _logger.debug("br.fill = %r." % br.fill)
    assert br.fill == b'\x00'

    br.fill = "0"
    _logger.debug("br.fill = %r." % br.fill)
    assert br.fill == b'\x00'

    br.fill = 1
    _logger.debug("br.fill = %r." % br.fill)
    assert br.fill == b'\x01'
def test_all():
    br0 = Objects.ByteRun()
    br0.img_offset = 0
    br0.len = 20

    br1 = Objects.ByteRun()
    br1.img_offset = 20
    br1.len = 30

    br2 = Objects.ByteRun()
    br2.img_offset = 50
    br2.len = 20

    brs_contiguous = Objects.ByteRuns()
    brs_contiguous.append(br0)
    brs_contiguous.append(br1)
    brs_contiguous.append(br2)

    brs_glommed = Objects.ByteRuns()
    brs_glommed.glom(br0)
    brs_glommed.glom(br1)
    brs_glommed.glom(br2)

    brs_discontig = Objects.ByteRuns()
    brs_discontig.glom(br0)
    brs_discontig.glom(br2)

    brs_backward = Objects.ByteRuns()
    brs_backward.glom(br1)
    brs_backward.glom(br0)

    assert len(brs_contiguous) == 3
    assert len(brs_glommed) == 1
    assert len(brs_discontig) == 2
    assert len(brs_backward) == 2

    assert brs_glommed[0].len == 70
    assert brs_backward[0].len == 30
    assert brs_backward[1].len == 20

    br_facet_data = Objects.ByteRuns(facet="data")
    br_facet_name = Objects.ByteRuns(facet="name")
    br_facet_default = Objects.ByteRuns()
    assert br_facet_data == br_facet_default
    assert br_facet_name != br_facet_data
    assert br_facet_name != br_facet_default
Exemple #6
0
def get_brs():
    logging.basicConfig(level=logging.DEBUG)
    _logger = logging.getLogger(os.path.basename(__file__))

    br = Objects.ByteRun()
    br.file_offset = 4128
    br.len = 133
    brs = Objects.ByteRuns()
    brs.append(br)
    return brs
Exemple #7
0
def test_all():

    _logger = logging.getLogger(os.path.basename(__file__))
    logging.basicConfig(level=logging.DEBUG)

    br1 = Objects.ByteRun(img_offset=1, len=1)
    br2 = Objects.ByteRun(img_offset=2, len=2)
    br3 = Objects.ByteRun(img_offset=4, len=3)

    dbr = Objects.ByteRuns()
    ibr = Objects.ByteRuns()
    nbr = Objects.ByteRuns()

    dbr.append(br1)
    ibr.append(br2)
    nbr.append(br3)

    dbr.facet = "data"
    ibr.facet = "inode"
    nbr.facet = "name"

    f1 = Objects.FileObject()
    f1.data_brs = dbr
    f1.inode_brs = ibr
    f1.name_brs = nbr

    assert f1.data_brs[0].img_offset == 1
    assert f1.inode_brs[0].img_offset == 2
    assert f1.name_brs[0].img_offset == 4

    e1 = f1.to_Element()
    #_logger.debug(f1)
    #_logger.debug(ET.tostring(e1))

    f2 = Objects.FileObject()

    f2.populate_from_Element(e1)
    #_logger.debug(f2)

    assert f2.data_brs[0].img_offset == 1
    assert f2.inode_brs[0].img_offset == 2
    assert f2.name_brs[0].img_offset == 4
def test_all():
    br1 = Objects.ByteRun()
    br1.img_offset = 512
    br1.len = 20

    br2 = copy.deepcopy(br1)

    assert br1 + br2 is None

    br2.img_offset += br1.len

    assert (br1 + br2).len == 40
Exemple #9
0
def test_hash_properties():
    dobj = Objects.DFXMLObject(version="1.2.0")

    fobj = Objects.FileObject()
    dobj.append(fobj)

    fobj.byte_runs = Objects.ByteRuns()
    br = Objects.ByteRun()
    fobj.byte_runs.append(br)

    fobj.filesize = len(TEST_BYTE_STRING)
    br.len = len(TEST_BYTE_STRING)

    hash_functions = {"md5", "sha1", "sha224", "sha256", "sha384", "sha512"}

    # Key: Hash function.
    # Value: Hash of the byte string b"test".
    hash_values = dict()

    for hash_function in sorted(hash_functions):
        hash_object = getattr(hashlib, hash_function)()
        hash_object.update(TEST_BYTE_STRING)
        hash_values[hash_function] = hash_object.hexdigest()
        _logger.debug("hash_values[%r] = %r." %
                      (hash_function, hash_values[hash_function]))

        setattr(fobj, hash_function, hash_values[hash_function])
        setattr(br, hash_function, hash_values[hash_function])

        assert getattr(fobj, hash_function) == hash_values[hash_function]
        assert getattr(br, hash_function) == hash_values[hash_function]

    # Do file I/O round trip.
    (tmp_filename, dobj_reconst) = libtest.file_round_trip_dfxmlobject(dobj)
    try:
        fobj_reconst = dobj_reconst.files[0]
        br_reconst = fobj_reconst.byte_runs[0]
        for hash_function in sorted(hash_functions):
            assert getattr(fobj_reconst,
                           hash_function) == hash_values[hash_function]
            assert getattr(br_reconst,
                           hash_function) == hash_values[hash_function]
    except:
        _logger.debug("tmp_filename = %r." % tmp_filename)
        raise
    os.remove(tmp_filename)
Exemple #10
0
    def parse(self, in_fh):
        """
        Returns a DFXMLObject.
        """
        dobj = Objects.DFXMLObject(version="1.2.0+")
        dobj.program = sys.argv[0]
        dobj.program_version = __version__
        dobj.command_line = " ".join(sys.argv)
        dobj.dc["type"] = "Disk image sector map"
        dobj.add_creator_library("Python", ".".join(map(str, sys.version_info[0:3]))) #A bit of a bend, but gets the major version information out.
        dobj.add_creator_library("Objects.py", Objects.__version__)
        dobj.add_creator_library("dfxml.py", Objects.dfxml.__version__)
        diobj = Objects.DiskImageObject()
        dobj.append(diobj)
        brs = Objects.ByteRuns()
        diobj.byte_runs = brs

        dobj.add_namespace("gddr", Objects.dfxml.XMLNS_DFXML + "#gddrescue")

        self._state = ParseState.FILE_OPENED
        self._disk_image_len = 0

        for (line_no, line) in enumerate(in_fh):
            self._line_no = line_no

            cleaned_line = line.strip()
            if cleaned_line.startswith("0x"):
                if self._state in (ParseState.TABLE_HEAD, ParseState.IN_TABLE):
                    self.transition(ParseState.IN_TABLE)
                else:
                    self.transition(ParseState.CURRENT_POS_RECORD)
            elif cleaned_line == "#      pos        size  status":
                self.transition(ParseState.TABLE_HEAD)
            elif cleaned_line == "# current_pos  current_status  current_pass":
                self.transition(ParseState.CURRENT_POS_HEAD)
            else:
                self.transition(ParseState.PRE_TABLE)

            if self._state != ParseState.IN_TABLE:
                continue

            br = Objects.ByteRun()

            line_parts = cleaned_line.split("  ")
            br.img_offset = int(line_parts[0], base=16)
            br.len = int(line_parts[1], base=16)

            self._disk_image_len = br.img_offset + br.len

            # TODO
            # Independent design decision, while awaiting a consensus design:
            #   Only report the byte runs ddrescue was able to collect.
            if line_parts[2] != "+":
                continue
            brs.append(br)

        diobj.filesize = self._disk_image_len
        _logger.info("diobj.filesize = %r." % diobj.filesize)

        self.transition(ParseState.STREAM_COMPLETE)
        return dobj
Exemple #11
0
def main():
    dobj = Objects.DFXMLObject(version="1.2.0")
    dobj.program = sys.argv[0]
    dobj.program_version = __version__
    dobj.command_line = " ".join(sys.argv)
    dobj.dc["type"] = "Example"
    dobj.add_creator_library("Python", ".".join(map(str, sys.version_info[0:3]))) #A bit of a bend, but gets the major version information out.
    dobj.add_creator_library("Objects.py", Objects.__version__)
    dobj.add_creator_library("dfxml.py", Objects.dfxml.__version__)

    vobj = Objects.VolumeObject()
    dobj.append(vobj)

    vobj.ftype_str = "examplefs"

    # Define file system position.
    vobj.byte_runs = Objects.ByteRuns()
    vbr = Objects.ByteRun()
    vobj.byte_runs.append(vbr)
    vbr.img_offset = FILE_SYSTEM_START
    vbr.len = DISK_IMAGE_SIZE - FILE_SYSTEM_START

    fobj_specs = [
      (
        "first_sector.bin",
        [
          (0, 512)
        ]
      ),
      (
        "first_four_kilobytes.bin",
        [
          (0, 4000)
        ]
      ),
      (
        "contiguous_before_bad_region.dat",
        [
          (FILE_SYSTEM_START + 4096*1, 4096)
        ]
      ),
      (
        "contiguous_around_bad_region_left_edge.dat",
        [
          (DAMAGE_REGION_START - 4096, 8192)
        ]
      ),
      (
        "contiguous_in_bad_region.dat",
        [
          (DAMAGE_REGION_START + 4096*1, 4096)
        ]
      ),
      (
        "contiguous_around_bad_region_right_edge.dat",
        [
          (GOOD_REGION_START - 4096*1, 8192)
        ]
      ),
      (
        "contiguous_after_bad_region.dat",
        [
          (GOOD_REGION_START + 4096*2, 4096)
        ]
      ),
      (
        "fragmented_all_before_bad_region.dat",
        [
          (FILE_SYSTEM_START + 4096*10, 4096),
          (FILE_SYSTEM_START + 4096*20, 4096),
          (FILE_SYSTEM_START + 4096*30, 4096)
        ]
      ),
      (
        "fragmented_all_after_bad_region.dat",
        [
          (GOOD_REGION_START + 4096*10, 4096),
          (GOOD_REGION_START + 4096*20, 4096),
          (GOOD_REGION_START + 4096*30, 4096)
        ]
      ),
      (
        "fragmented_all_inside_bad_region.dat",
        [
          (DAMAGE_REGION_START + 4096*10, 4096),
          (DAMAGE_REGION_START + 4096*20, 4096),
          (DAMAGE_REGION_START + 4096*30, 4096)
        ]
      ),
      (
        "fragmented_beginning_inside_bad_region.dat",
        [
          (DAMAGE_REGION_START + 4096*40, 4096),
          (GOOD_REGION_START + 4096*40, 4096)
        ]
      ),
      (
        "fragmented_middle_inside_bad_region.dat",
        [
          (FILE_SYSTEM_START + 4096*50, 4096),
          (DAMAGE_REGION_START + 4096*50, 4096),
          (GOOD_REGION_START + 4096*50, 4096)
        ]
      ),
      (
        "fragmented_end_inside_bad_region.dat",
        [
          (FILE_SYSTEM_START + 4096*60, 4096),
          (DAMAGE_REGION_START + 4096*60, 4096)
        ]
      ),
      (
        "after_disk_image_end.dat",
        [
          (DISK_IMAGE_SIZE + 4096*1000, 4096)
        ]
      ),
      (
        "fragmented_partially_recoverable_directory",
        [
          (FILE_SYSTEM_START + 4096*170, 4096),
          (DAMAGE_REGION_START + 4096*170, 4096),
          (GOOD_REGION_START + 4096*170, 4096),
        ]
      ),
      (
        "fragmented_partially_recoverable_directory/child_file_1",
        [
          (FILE_SYSTEM_START + 4096*180, 4096)
        ]
      ),
      (
        "fragmented_partially_recoverable_directory/child_file_2",
        [
          (FILE_SYSTEM_START + 4096*190, 4096)
        ]
      ),
      (
        "fragmented_partially_recoverable_directory/child_file_3",
        [
          (FILE_SYSTEM_START + 4096*200, 4096)
        ]
      ),
      (
        "fragmented_partially_recoverable_directory/child_file_4",
        [
          (FILE_SYSTEM_START + 4096*210, 4096)
        ]
      ),
      (
        "fragmented_partially_recoverable_directory/child_file_9",
        [
          (GOOD_REGION_START + 4096*180, 4096)
        ]
      )
    ]
    for fobj_spec in fobj_specs:
        fobj = Objects.FileObject()
        vobj.append(fobj)

        fobj.filename = fobj_spec[0]
        fobj.alloc = True
        # Naming convention for this sample - the .bin files are virtual files that reference a region outside of the file system.
        if fobj.filename == "fragmented_partially_recoverable_directory":
            fobj.name_type = "d"
        elif fobj.filename.endswith(".bin"):
            fobj.name_type = "v"
        else:
            fobj.name_type = "r"

        fobj.data_brs = Objects.ByteRuns()
        for interval in fobj_spec[1]:
            br = Objects.ByteRun()
            fobj.data_brs.append(br)
            br.img_offset = interval[0]
            br.len = interval[1]
        fobj.filesize = sum([br.len for br in fobj.data_brs])

    dobj.print_dfxml()