Skip to content

Accumulate SHA-1 digest across all class entries for the bytecode hash (#133) - #147

Merged
elharo merged 7 commits into
masterfrom
fix/issue-133-bytecode-hash-all-entries
Aug 7, 2026
Merged

Accumulate SHA-1 digest across all class entries for the bytecode hash (#133)#147
elharo merged 7 commits into
masterfrom
fix/issue-133-bytecode-hash-all-entries

Conversation

@elharo

@elharo elharo commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Fixes #133

Problem

JarBytecodeHashAnalyzer.computeHash() overwrote result on each loop iteration, so the computed bytecode hash only covered the last class entry in the JAR:

for (JarEntry entry : entries) {
    try (InputStream is = jarAnalyzer.getEntryInputStream(entry)) {
        result = DigestUtils.sha1Hex(is); // overwrites previous result
    }
}

As a result, two JARs with completely different class sets could produce the same bytecodeHash whenever their last-sorted class entry was identical, contradicting the analyzer's contract of detecting an exact copy of the file's class data.

Fix

The SHA-1 digest is now updated incrementally across every class entry (in the stable, name-sorted order produced by JarAnalyzer), and the final digest is hex-encoded once after the loop.

Tests

Added JarBytecodeHashAnalyzerTest with two tests, both verified to fail before the fix and pass after:

  • computeHashCoversAllClassEntries: the hash of codec.jar (14 classes) equals the SHA-1 of the concatenated class bytes.
  • distinctClassSetsProduceDistinctHashes: two JARs sharing only the last-sorted class entry produce different hashes (they previously hashed identically).

Previously the digest was overwritten on each loop iteration, so the
computed hash only covered the last class entry in the JAR. Two JARs
with completely different class sets could therefore produce the same
bytecode hash when their last-sorted class entry was identical.

The digest is now updated incrementally across every class entry (in the
stable, name-sorted order), so the hash covers the full class data.
@elharo
elharo requested a review from ppkarwasz August 3, 2026 13:26

@ppkarwasz ppkarwasz left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM

@elharo
elharo merged commit 6dae912 into master Aug 7, 2026
15 checks passed
@elharo
elharo deleted the fix/issue-133-bytecode-hash-all-entries branch August 7, 2026 13:15
@github-actions github-actions Bot added this to the 3.2.1 milestone Aug 7, 2026
@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown

@elharo Please assign appropriate label to PR according to the type of change.

@elharo elharo added the bug Something isn't working label Aug 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bytecode hash only captures last class file in JarBytecodeHashAnalyzer

2 participants