Skip to content

Commit 14f5385

Browse files
author
Gauvain Pocentek
committed
fix: convert # to %23 in URLs
Refactor a bit to handle this change, and add unit tests. Closes #779
1 parent 794d64c commit 14f5385

File tree

3 files changed

+51
-3
lines changed

3 files changed

+51
-3
lines changed

gitlab/mixins.py

+4-3
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
from gitlab import cli
2121
from gitlab import exceptions as exc
2222
from gitlab import types as g_types
23+
from gitlab import utils
2324

2425

2526
class GetMixin(object):
@@ -42,7 +43,7 @@ def get(self, id, lazy=False, **kwargs):
4243
GitlabGetError: If the server cannot perform the request
4344
"""
4445
if not isinstance(id, int):
45-
id = id.replace("/", "%2F")
46+
id = utils.clean_str_id(id)
4647
path = "%s/%s" % (self.path, id)
4748
if lazy is True:
4849
return self._obj_cls(self, {self._obj_cls._id_attr: id})
@@ -299,7 +300,7 @@ def set(self, key, value, **kwargs):
299300
Returns:
300301
obj: The created/updated attribute
301302
"""
302-
path = "%s/%s" % (self.path, key.replace("/", "%2F"))
303+
path = "%s/%s" % (self.path, utils.clean_str_id(key))
303304
data = {"value": value}
304305
server_data = self.gitlab.http_put(path, post_data=data, **kwargs)
305306
return self._obj_cls(self, server_data)
@@ -322,7 +323,7 @@ def delete(self, id, **kwargs):
322323
path = self.path
323324
else:
324325
if not isinstance(id, int):
325-
id = id.replace("/", "%2F")
326+
id = utils.clean_str_id(id)
326327
path = "%s/%s" % (self.path, id)
327328
self.gitlab.http_delete(path, **kwargs)
328329

gitlab/tests/test_utils.py

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# -*- coding: utf-8 -*-
2+
#
3+
# Copyright (C) 2019 Gauvain Pocentek <gauvain@pocentek.net>
4+
#
5+
# This program is free software: you can redistribute it and/or modify
6+
# it under the terms of the GNU Lesser General Public License as published by
7+
# the Free Software Foundation, either version 3 of the License, or
8+
# (at your option) any later version.
9+
#
10+
# This program is distributed in the hope that it will be useful,
11+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
# GNU Lesser General Public License for more details.
14+
#
15+
# You should have received a copy of the GNU Lesser General Public License
16+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
17+
18+
try:
19+
import unittest
20+
except ImportError:
21+
import unittest2 as unittest
22+
23+
from gitlab import utils
24+
25+
26+
class TestUtils(unittest.TestCase):
27+
def test_clean_str_id(self):
28+
src = "nothing_special"
29+
dest = "nothing_special"
30+
self.assertEqual(dest, utils.clean_str_id(src))
31+
32+
src = "foo#bar/baz/"
33+
dest = "foo%23bar%2Fbaz%2F"
34+
self.assertEqual(dest, utils.clean_str_id(src))
35+
36+
def test_sanitized_url(self):
37+
src = "http://localhost/foo/bar"
38+
dest = "http://localhost/foo/bar"
39+
self.assertEqual(dest, utils.sanitized_url(src))
40+
41+
src = "http://localhost/foo.bar.baz"
42+
dest = "http://localhost/foo%2Ebar%2Ebaz"
43+
self.assertEqual(dest, utils.sanitized_url(src))

gitlab/utils.py

+4
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ def copy_dict(dest, src):
4747
dest[k] = v
4848

4949

50+
def clean_str_id(id):
51+
return id.replace("/", "%2F").replace("#", "%23")
52+
53+
5054
def sanitized_url(url):
5155
parsed = six.moves.urllib.parse.urlparse(url)
5256
new_path = parsed.path.replace(".", "%2E")

0 commit comments

Comments
 (0)