Skip to content

ZipContent.Entry hasNameStartingWith ignores the offset of virtualized nested directory names - #52299

Merged
wilkinsona merged 1 commit into
spring-projects:4.0.xfrom
zhoubiao188:fix-loader-nested-entry-name-prefix
Oct 27, 2026
Merged

wilkinsona merged 1 commit into
spring-projects:4.0.xfrom
zhoubiao188:fix-loader-nested-entry-name-prefix

Conversation

@zhoubiao188

Copy link
Copy Markdown
Contributor

When ZipContent is opened for a nested directory (Kind.NESTED_DIRECTORY), entry names are virtualized: the name stored in the central directory record includes the directory name, while getName() strips it using nameOffsetLookups. hasNameStartingWith reads the record directly but doesn't strip the same offset, so it compares the prefix with the complete name.

For a nested directory d/ containing 9.dat, getName() returns 9.dat, but hasNameStartingWith("9.dat") returns false until getName() happens to have been called:

try (ZipContent zip = ZipContent.open(path, "d/")) {
    Entry entry = zip.getEntry(0);
    entry.hasNameStartingWith("9.dat");   // false
    entry.getName();                      // "9.dat"
    entry.hasNameStartingWith("9.dat");   // true (name is now cached)
}

This contradicts the method's own contract and makes the result depend on call order. It also prevents MetaInfVersionsInfo from seeing versioned entries in nested directory content, because it relies on hasNameStartingWith("META-INF/versions/").

Fix

Apply the same nameOffsetLookups offset that getName() uses. A regression test is included.

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue that has not yet been triaged. Contributions will not be accepted. label Oct 19, 2026
@wilkinsona wilkinsona self-assigned this Oct 27, 2026
@wilkinsona wilkinsona added type: bug A general bug and removed status: waiting-for-triage An issue that has not yet been triaged. Contributions will not be accepted. labels Oct 27, 2026
@wilkinsona wilkinsona added this to the 4.0.x milestone Oct 27, 2026
`ZipContent.Entry#hasNameStartingWith` reads the name directly from
the central directory record, but doesn't take into account the
offset of names that are virtualized for nested directory content.
For such entries the prefix is compared with the complete name,
including the directory, so the method returns `false` for a name
that `getName()` returns, and the result depends on whether
`getName()` was called first to populate the cache.

Apply the same offset that is used by `getName()`.

Signed-off-by: zhoubiao188 <32508238+zhoubiao188@users.noreply.github.com>

See spring-projectsgh-52299
@wilkinsona
wilkinsona force-pushed the fix-loader-nested-entry-name-prefix branch from 71bdb8c to 9e15e9a Compare October 27, 2026 14:13
@wilkinsona wilkinsona modified the milestones: 4.0.x, 4.0.10 Oct 27, 2026
@wilkinsona
wilkinsona merged commit b6f10bc into spring-projects:4.0.x Oct 27, 2026
2 checks passed
@wilkinsona

Copy link
Copy Markdown
Member

Thanks again, @zhoubiao188.

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

Labels

type: bug A general bug

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants