Skip to content

Add jprove wrapper, fix interpreter bugs, improve Archive::Zip#373

Merged
fglock merged 6 commits into
masterfrom
feature/add-jprove
Mar 25, 2026
Merged

Add jprove wrapper, fix interpreter bugs, improve Archive::Zip#373
fglock merged 6 commits into
masterfrom
feature/add-jprove

Conversation

@fglock
Copy link
Copy Markdown
Owner

@fglock fglock commented Mar 25, 2026

Summary

This PR adds the jprove wrapper script for running Perl tests, fixes bugs in the bytecode disassembler and interpreter, and significantly improves the Archive::Zip implementation for ExifTool compatibility.

Changes

  • Add jprove wrapper: Import prove, App::Prove, and IO::Select modules to enable running Perl test files with the standard prove interface
  • Add jprove documentation: Update testing guide with jprove usage instructions
  • Fix bytecode disassembler: Fix POST_AUTOINCREMENT and POST_AUTODECREMENT disassembly to correctly read both registers (destination and source)
  • Fix interpreter array operations: Fix array element assignment and stale data bugs
  • Fix RuntimeList NPE: Handle null array elements (from delete operations) in list assignment
  • Archive::Zip improvements: Major improvements for ExifTool compatibility

RuntimeList NPE Fix

Arrays in Perl can have null elements after delete operations (e.g., delete $array[i]). The setFromList fast path was not handling these null elements, causing a NullPointerException when copying array values during list assignment. This was causing ExifTool DNG.t and Nikon.t write tests to fail.

Result: DNG.t (3/3) and Nikon.t (9/9) tests now pass.

Archive::Zip Improvements

The Archive::Zip implementation has been significantly enhanced to support ExifTool's test suite:

  • readFromFileHandle: Added method to read ZIP files from file handles (required by ExifTool)
  • zipfileComment: Added method to get/set ZIP file comments
  • contents(): Fixed to return (content, status) in list context
  • Member accessor methods: Added lastModFileDateTime, versionNeededToExtract, bitFlag, fileComment
  • Raw DOS timestamp extraction: Parse ZIP central directory directly to extract raw DOS timestamps, bypassing Java's timezone conversion

The key fix was that Java's ZipEntry.getTime() uses extended Unix timestamps when available and applies timezone conversion, which does not match Perl's Archive::Zip behavior of returning the raw DOS timestamp directly from the ZIP file header. We now parse the central directory ourselves to get the correct raw timestamps.

Result: All 8 ExifTool ZIP.t tests now pass.

Disassembler Fix Details

The POST_AUTOINCREMENT and POST_AUTODECREMENT opcodes take two registers (destination and source), but the disassembler was only reading one. This caused the bytecode output to be misaligned and confusing when using --interpreter --disassemble.

The interpreter execution was always correct - only the visualization was wrong.

Test plan

  • make passes (all unit tests)
  • Verified disassembly output is now correct for POST_AUTOINCREMENT/DECREMENT
  • Verified interpreter executes loops correctly
  • All 8 ExifTool ZIP.t tests pass
  • All 3 ExifTool DNG.t tests pass
  • All 9 ExifTool Nikon.t tests pass

Generated with Devin

@fglock fglock force-pushed the feature/add-jprove branch from c7e68d2 to 83a6f72 Compare March 25, 2026 13:31
@fglock fglock changed the title Add jprove wrapper and fix bytecode disassembler Add jprove wrapper, fix interpreter bugs, improve Archive::Zip Mar 25, 2026
fglock and others added 6 commits March 25, 2026 17:24
The POST_AUTOINCREMENT and POST_AUTODECREMENT opcodes take two registers
(destination and source), but the disassembler was only reading one.
This caused the disassembly output to be misaligned and confusing.

The actual interpreter execution was correct - only the disassembly
output was wrong.

Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
1. Fix run_exiftool_tests.pl to properly detect incomplete tests:
   - Add 'incomplete' status for tests that ran fewer than planned
   - Check for incomplete tests BEFORE marking as pass
   - Add missing test count to summary
   - Calculate pass rate against planned tests

2. Fix interpreter array operations (push/pop/shift/unshift):
   - Add getArrayFromRegister() helper to handle RuntimeList conversion
   - Prevents ClassCastException when register contains RuntimeList
   - Follows same pattern as executeDerefArray() for consistency

These fixes improve ExifTool test accuracy from falsely showing 113 passed
to correctly showing 91 fully passed and 22 incomplete.

Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
The register array pooling optimization introduced in commit 9d68652
was causing subtle bugs where registers retained stale values from
previous executions. This manifested as Not a HASH reference errors
in ExifTool Writer.t test (5/61 tests passing -> 61/61 after fix).

The issue was that when reusing a cached register array, old values
remained even after clearing with Arrays.fill() - the root cause needs
further investigation. For now, disable pooling to ensure correctness.

ExifTool Writer.t: 5/61 -> 61/61

Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
- Add readFromFileHandle method to read ZIP files from file handles
- Add zipfileComment() to get/set ZIP file comment
- Fix contents() to return (content, status) in list context
- Add member accessor methods: lastModFileDateTime (MS-DOS format),
  versionNeededToExtract, bitFlag, fileComment
- Add getRawDosTime helper for MS-DOS timestamp extraction
- Add unixTimeToDosFmt for Unix to MS-DOS timestamp conversion

This improves compatibility with ExifTool's HandleMember() function.
Tests 1, 3, 7, 8 pass. Tests 2, 4, 5, 6 have timestamp timezone
issues due to Java's ZipEntry converting DOS timestamps to local time.

Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Java's ZipEntry uses extended Unix timestamps when available, which
causes timezone conversion issues. This commit adds methods to parse
the ZIP central directory directly to extract raw DOS timestamps:

- extractRawDosTimestamps: Parse from file path
- extractRawDosTimestampsFromBytes: Parse from byte array

These methods are used in read() and readFromFileHandle() to provide
the correct raw DOS timestamps that Perl's Archive::Zip returns.

This fixes all 8 ExifTool ZIP.t tests.

Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Arrays in Perl can have null elements after delete operations (e.g.,
delete $array[i]). The setFromList fast path was not handling these
null elements, causing a NullPointerException when copying array
values during list assignment.

This fixes ExifTool DNG.t and Nikon.t write tests which use arrays
that have had elements deleted.

Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@fglock fglock force-pushed the feature/add-jprove branch from 8accc4b to 7c121df Compare March 25, 2026 16:25
@fglock fglock merged commit 585103c into master Mar 25, 2026
2 checks passed
@fglock fglock deleted the feature/add-jprove branch March 25, 2026 16:37
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.

1 participant