Merge ~cjwatson/launchpad:artifactory-strip-trailing-backslashes into launchpad:master

Proposed by Colin Watson
Status: Merged
Approved by: Colin Watson
Approved revision: 1201cff437cdf0447750a5f8f8c6d8db0ce98994
Merge reported by: Otto Co-Pilot
Merged at revision: not available
Proposed branch: ~cjwatson/launchpad:artifactory-strip-trailing-backslashes
Merge into: launchpad:master
Diff against target: 35 lines (+8/-5)
2 files modified
lib/lp/archivepublisher/artifactory.py (+7/-4)
lib/lp/archivepublisher/tests/test_artifactory.py (+1/-1)
Reviewer Review Type Date Requested Status
Jürgen Gmach Approve
Review via email: mp+434495@code.launchpad.net

Commit message

Strip trailing backslashes from Artifactory property values

Description of the change

I've previously established empirically that backslashes must not be quoted when setting Artifactory properties (contrary to the public documentation), and the `encode_properties` function used internally when setting properties behaves as follows:

    >>> from collections import OrderedDict
    >>> from artifactory import encode_properties
    >>> properties = OrderedDict([("key1", "\\;=|,\\"), ("key2", "value")])
    >>> print(encode_properties(properties))
    key1=\;\=\|\,\;key2=value

This encoding clearly leaves no way to separate the fields unambiguously, and the result is that ";key2=value" ends up being appended to the value of the "key1" property, which is no good.

Stripping trailing backslashes is a horrible workaround, but I don't see a way around it given how the Artifactory API works. I expect trailing backslashes in property values to be extremely rare in practice, and they'll only show up in informational properties auto-populated by Artifactory itself, not by anything functional.

To post a comment you must log in.
Revision history for this message
Jürgen Gmach (jugmac00) wrote :

I am curious - did you get in touch with Jfrog about the incorrect documentation/API?

review: Approve
Revision history for this message
Colin Watson (cjwatson) wrote :

I'm afraid I considered it and decided I couldn't face figuring out how to do so. (I'd probably feel differently if it were an open source project!)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/lib/lp/archivepublisher/artifactory.py b/lib/lp/archivepublisher/artifactory.py
2index 9af731b..9fc4fc7 100644
3--- a/lib/lp/archivepublisher/artifactory.py
4+++ b/lib/lp/archivepublisher/artifactory.py
5@@ -360,11 +360,14 @@ class ArtifactoryPoolEntry:
6 # "|", and "=" (and handles URL-encoding at a lower layer). In
7 # practice, backslash must apparently not be quoted, and ";" must be
8 # quoted as otherwise ";" within items will be confused with a
9- # property separator. This is not very satisfactory as we're
10- # essentially playing core wars with the artifactory module, but
11- # this solves the problem for now.
12+ # property separator; we must also remove any trailing backslashes as
13+ # they'll cause any following property to be interpreted as part of
14+ # this property value. This is not very satisfactory as we're
15+ # essentially playing core wars with the artifactory module, and
16+ # removing trailing backslashes unavoidably loses some information,
17+ # but this solves the problem for now.
18 new_properties = {
19- key: [v.replace(";", r"\;") for v in value]
20+ key: [v.rstrip("\\").replace(";", r"\;") for v in value]
21 for key, value in new_properties.items()
22 }
23 if old_properties != new_properties:
24diff --git a/lib/lp/archivepublisher/tests/test_artifactory.py b/lib/lp/archivepublisher/tests/test_artifactory.py
25index 730e8a9..4179c2e 100644
26--- a/lib/lp/archivepublisher/tests/test_artifactory.py
27+++ b/lib/lp/archivepublisher/tests/test_artifactory.py
28@@ -1446,7 +1446,7 @@ class TestArtifactoryPoolFromLibrarian(TestCaseWithFactory):
29 )
30
31 self.assertEqual(
32- ["text with special characters: ;=|,\\"],
33+ ["text with special characters: ;=|,"],
34 path.properties["pypi.summary"],
35 )
36

Subscribers

People subscribed via source and target branches

to status/vote changes: