Skip to content

fix(ivy,osgi): encode PURL components instead of formatting them - #1351

Merged
mstykow merged 2 commits into
mainfrom
fix/encode-ivy-and-osgi-purls
Aug 11, 2026
Merged

fix(ivy,osgi): encode PURL components instead of formatting them#1351
mstykow merged 2 commits into
mainfrom
fix/encode-ivy-and-osgi-purls

Conversation

@mstykow

@mstykow mstykow commented Aug 11, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Neither ivy nor osgi appears in the central PURL normalizer's rule list, so nothing downstream re-encodes them — a hand-formatted string is exactly what ships.
  • Both take components from free-form input: ivy from XML attributes, OSGi from manifest headers. A space silently loses the version on re-parse: pkg:ivy/org with space/mod?x@1.0 re-parses as pkg:ivy/org%20with%20space/mod, and pkg:osgi/my bundle?x@1.0.0 as pkg:osgi/my%20bundle.
  • A # in an OSGi Require-Bundle became a subpath rather than part of the name.

Scope and exclusions

  • Included: ivy package identity and dependencies, OSGi bundle identity, Import-Package and Require-Bundle dependencies — all through the shared encoders added in fix(purl): encode opam, swift and conan PURL components #1350.
  • Explicit exclusions: still no change to the types the crate rewrites (github, npm, hex, deb, bitbucket, pypi); those need a case decision and are handled separately.

How to verify

mkdir -p /tmp/x/META-INF
printf 'Bundle-SymbolicName: my bundle?x\nBundle-Version: 1.0.0\nImport-Package: com.foo bar\nRequire-Bundle: req bundle#z\n' > /tmp/x/META-INF/MANIFEST.MF
provenant --package --json-pp - /tmp/x | jq '[.files[].package_data[] | {purl, deps: [.dependencies[].purl]}]'

Before: pkg:osgi/my bundle?x@1.0.0 — re-parsing drops ?x@1.0.0 entirely. After: pkg:osgi/my%20bundle%3Fx@1.0.0, which round-trips and decodes back to name my bundle?x with version 1.0.0.

The ivy equivalent is worth checking too, since it is the one where the namespace also needs encoding while keeping its / separator.

Intentional differences from Python

  • None.

Expected-output fixture changes

  • None. No fixture used a component needing encoding; covered by new unit tests that assert the encoded string, parse it back, and check the decoded namespace, name, version and subpath separately — the version assertions are the ones that would have caught the silent loss.

Neither type appears in the central PURL normalizer's rule list, so nothing
downstream re-encodes them and a hand-formatted string is exactly what ships.

Both take their components from free-form input — ivy from XML attributes, OSGi
from manifest headers — and a space truncated the PURL on re-parse, taking the
version with it: `pkg:ivy/org with space/mod?x@1.0` re-parses as
`pkg:ivy/org%20with%20space/mod`, and `pkg:osgi/my bundle?x@1.0.0` as
`pkg:osgi/my%20bundle`. A `#` in an OSGi `Require-Bundle` became a subpath rather
than part of the name.

Route every site through the shared encoders. An ivy dependency without an
organisation keeps its name-only form, now encoded too.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Maxim Stykow <maxim.stykow@gmail.com>
@greptile-apps

greptile-apps Bot commented Aug 11, 2026

Copy link
Copy Markdown

Greptile Summary

The PR replaces hand-formatted Ivy and OSGi PURLs with shared component encoders and moves field bounding into those helpers.

  • Encodes Ivy namespaces, names, revisions, and dependencies while preserving component structure.
  • Encodes OSGi bundle identities, imported packages, and required bundles.
  • Adds round-trip tests for spaces and reserved characters.
  • Removes serialized-PURL truncation from Ivy and opam paths, but the OSGi manifest finalization still performs it.

Confidence Score: 4/5

The PR is not yet safe to merge because sufficiently large encoded OSGi components can still produce truncated, malformed, or versionless PURLs.

OSGi PURLs are now encoded correctly, but manifest finalization still truncates the serialized identity and dependency strings after encoding, leaving the previously reported corruption path outstanding.

Files Needing Attention: src/parsers/maven/manifest.rs

Important Files Changed

Filename Overview
src/parsers/utils.rs Bounds decoded components before constructing simple and namespaced PURLs and documents that callers must not truncate serialized results.
src/parsers/ivy.rs Routes Ivy identity and dependency PURLs through shared encoders and removes post-construction truncation.
src/parsers/maven/manifest.rs Routes OSGi identities and dependencies through the encoder, but common finalization still truncates the serialized PURLs afterward.
src/parsers/ivy_test.rs Adds round-trip coverage for encoded Ivy namespace, name, revision, and dependency components.
src/parsers/maven/manifest_test.rs Adds OSGi reserved-character round-trip coverage but does not cover encoded output crossing the field limit.
src/parsers/opam.rs Stops truncating serialized opam dependency PURLs after helper construction.

Comments Outside Diff (1)

  1. src/parsers/maven/manifest.rs, line 256-258 (link)

    P1 Encoded OSGi PURLs remain truncated

    When an OSGi bundle or dependency name contains enough percent-encoded characters for its serialized PURL to exceed the field limit, this finalization truncates the PURL after encoding, splitting an escape or removing the version and emitting a malformed or incorrect package identity.

Reviews (2): Last reviewed commit: "fix(purl): bound PURL components before ..." | Re-trigger Greptile

Comment thread src/parsers/ivy.rs Outdated
Greptile review: applying `truncate_field` to an assembled PURL can cut a percent
escape in half or drop a trailing component, turning a valid PURL into one that
no longer parses — the opposite of what encoding these components achieved.

Bound the name, namespace and version inside the shared builders instead, where
truncation lands on a decoded component and the structure survives. Callers no
longer truncate the result.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Maxim Stykow <maxim.stykow@gmail.com>
@mstykow
mstykow merged commit da8b5f5 into main Aug 11, 2026
13 checks passed
@mstykow
mstykow deleted the fix/encode-ivy-and-osgi-purls branch August 11, 2026 23:34
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