Skip to content

Cleanup ASIF calculations#86

Open
Schamper wants to merge 3 commits into
mainfrom
cleanup-asif
Open

Cleanup ASIF calculations#86
Schamper wants to merge 3 commits into
mainfrom
cleanup-asif

Conversation

@Schamper

Copy link
Copy Markdown
Member

With the information from https://github.com/huven/asif-format and a fresher mind, I took another look at some of the calculations made in the ASIF implementation. I believe these new changes to be much more accurate.

@codecov

codecov Bot commented Jun 16, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 89.47368% with 6 lines in your changes missing coverage. Please review.
✅ Project coverage is 80.92%. Comparing base (9736c31) to head (738119e).

Files with missing lines Patch % Lines
dissect/hypervisor/disk/asif.py 89.47% 6 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main      #86      +/-   ##
==========================================
+ Coverage   80.89%   80.92%   +0.03%     
==========================================
  Files          26       26              
  Lines        2381     2411      +30     
==========================================
+ Hits         1926     1951      +25     
- Misses        455      460       +5     
Flag Coverage Δ
unittests 80.92% <89.47%> (+0.03%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@Schamper
Schamper requested a review from twiggler July 8, 2026 14:52
Comment thread dissect/hypervisor/disk/asif.py Outdated
read_length = min(length, self.asif.chunk_size)
if chunk == 0:
if (table := self.directory.table(offset // self.asif._size_per_table)) is None:
read_length = min(length, self.asif._size_per_table)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Read offsets are aligned to chunk_size, not to table_size.

If a read starts halfway into a sparse table, is it possible that we silently return zeros for the data of the next table?

Perhaps it is structurally cleaner to nest the iteration and have a outer loop over tables, and inner loop over chunks?

Comment thread dissect/hypervisor/disk/asif.py Outdated
chunk = table.entries[entry_index] & 0x7FFFFFFFFFFFFF

read_length = min(length, self.asif.chunk_size)
if chunk == 0:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(found with AI):

https://github.com/huven/asif-format

clams there is a data chunk status = 11, and suggests the following read behavior:

Data chunk status = 11: consult the corresponding sector >status in the bitmap chunk; return all zeros for uninitialized >sectors (00) and unmapped sectors (10), read physical chunk >for initialized sectors (01), and reject bitmap state 11.

result.append(self.asif.fh.read(self.asif.block_size))
elif block_status == 0b10:
# unmapped
result.append(b"\x00" * self.asif.block_size)

@twiggler twiggler Jul 22, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to trigger this code-path by the test fixture?

Perhaps patch the fixture in-memory and turn a logical chunk into a partial chunk, and hand craft the associated bitmap?

)

# Read the bitmap
bitmap_chunk = table.entries[bitmap_entry_index] & 0x7FFFFFFFFFFFFF

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The bitmap is possibly re-read in the case of consecutive partial chunks.

Perhaps the bitmap can be cached.
(can be deferred)


read_length = min(length, self.asif.chunk_size)
if chunk == 0:
table_index, offset_in_table = divmod(offset, self.asif._size_per_table)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_read is mixing three levels of abstraction:

  1. Stream bookkeeping.
  2. Address translation
  3. Producing bytes

Perhaps push the layout math to a Table class.

Perhaps introduce a read_partial_chunk method.

(can be deferred)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants