Change in PURL since syft v.1.19.0

Hi team,

I was comparing output of syft, and saw some changed i purl of packages in debian.

can you please confirm this is the desired behave?

Before:
"purl": "pkg:deb/debian/zlib1g@1:1.2.7.dfsg-13?arch=amd64&distro=debian-7&upstream=zlib"

After:
"purl": "pkg:deb/debian/zlib1g@1**%3A**1.2.7.dfsg-13?arch=amd64&distro=debian-7&upstream=zlib"

the image is -
m3tr0x/avivm-sushi:0.0.2

(I saw few more packages with the same change)

Thanks!

Hi @TimBrown1611 thanks for the post.

Can you confirm the difference you’re seeing?

I see the following diff (repeated on basically every deb):

-"pkg:deb/debian/zlib1g@1:1.2.7.dfsg-13?arch=amd64&distro=debian-7&upstream=zlib"
+"pkg:deb/debian/zlib1g@1%3A1.2.7.dfsg-13?arch=amd64&distro=debian-7&upstream=zlib"

where the only change is that the : in between the epoch and the rest of the version is now percent-encoded. However, in your example, there are some ** in the diff, as in zlib1g@1**%3A**1.2.7.dfsg-13. Can you confirm that you’re really seeing these **, or is there some redaction or abbreviation in what you posted? (The percent encoding worries me less than the **.)

Hi!
not the ** (it is to make it bold)

the %3A is the diff

Thanks for getting back to me so quickly @TimBrown1611!

The change you are seeing is because of Escape each segment according to spec by jkugler · Pull Request #23 · anchore/packageurl-go · GitHub

I believe this change is intentional and correct. Is it causing any issues for you?

not an issue that I’ve noticed, just wanted to make sure it is OK :slight_smile:

Checking the PURL spec,

It says: purl-spec/PURL-SPECIFICATION.rst at 1951d217bde29590a73f075db4ab71cc00011459 · package-url/purl-spec · GitHub

A version must be a percent-encoded string.

But at purl-spec/PURL-TYPES.rst at 1951d217bde29590a73f075db4ab71cc00011459 · package-url/purl-spec · GitHub

It gives the example pkg:deb/debian/attr@1:2.4.47-2%2Bb1?arch=amd64 which percent encodes + but not :, in the version, which is pretty confusing.

@Christopher_Phillips did this come up at all when discussing this? I feel like the PURL spec is trying to tell me 2 different things.

For RPMs, the epoch is a qualifier (see purl-spec/PURL-TYPES.rst at 1951d217bde29590a73f075db4ab71cc00011459 · package-url/purl-spec · GitHub), so we shouldn’t have : in the version string, so RPMs shouldn’t be changing I think.

@popey do debs have an epoch? Or do they use a different term for the bit of the version before the :? Does it mean something different than with RPMs?

Yes! This question did come up when we were discussing the change with the user who submitted the PR, but only with regards to the name component not version.

You’re correct that the documentation from their seems to convey two different things. PURL TYPES has examples where a version component is not percent encoded, but the PURL-SPECIFICATION.rst says

  • A version must be a percent-encoded string

The conclusion on the PR/issues was that If we produce a name or namespace that is not percent encoded we are in violation of the spec. I think the same logic would apply to version here.

Maybe we should ask about this seeming conflict for the version component that we see between PURL-TYPES and PURL-SPECIFICATION

We opted to follow PURL-SPECIFICATION regarding the name component so that our behavior would be equivalent with the upstream packageurl-go library which percent encodes purl components in this way:

Our PURL library has a couple of other changes that are ahead of main in the upstream library which is why we opt to keep the fork.

In this comment we called out the change under the heading Test to look at that's actually related to the code change Note this was with regards to / under namespace, but I believe the same logic of why we went with percent encoded / in namespace can be applied to which we percent encode : in the name parameter.

Here is the discussion from live stream:

It’s also worth mentioning that previous versions of syft using the old behavior would generate PURL that failed on submission to other PURL library with a : not percent encoded in the name parameter.

Yup!

Here’s the version section of the debian packaging guide.

5.6.12. Version

The version number of a package. The format is: [epoch:]upstream_version[-debian_revision].

The three components here are:

epoch

This is a single (generally small) unsigned integer. It may be omitted, in which case zero is assumed.

Epochs can help when the upstream version numbering scheme changes, but they must be used with care. You should not change the epoch, even in experimental, without getting consensus on debian-devel first.