Show More
@@ -816,7 +816,7 b' class DiffProcessor(object):' | |||||
816 | return b''.join(raw_diff), chunks, stats |
|
816 | return b''.join(raw_diff), chunks, stats | |
817 |
|
817 | |||
818 | def _safe_id(self, idstring): |
|
818 | def _safe_id(self, idstring): | |
819 | """Make a string safe for including in an id attribute. |
|
819 | r"""Make a string safe for including in an id attribute. | |
820 |
|
820 | |||
821 | The HTML spec says that id attributes 'must begin with |
|
821 | The HTML spec says that id attributes 'must begin with | |
822 | a letter ([A-Za-z]) and may be followed by any number |
|
822 | a letter ([A-Za-z]) and may be followed by any number | |
@@ -828,8 +828,8 b' class DiffProcessor(object):' | |||||
828 | Whitespace is transformed into underscores, and then |
|
828 | Whitespace is transformed into underscores, and then | |
829 | anything which is not a hyphen or a character that |
|
829 | anything which is not a hyphen or a character that | |
830 | matches \w (alphanumerics and underscore) is removed. |
|
830 | matches \w (alphanumerics and underscore) is removed. | |
|
831 | """ | |||
831 |
|
832 | |||
832 | """ |
|
|||
833 | # Transform all whitespace to underscore |
|
833 | # Transform all whitespace to underscore | |
834 | idstring = re.sub(r'\s', "_", f'{idstring}') |
|
834 | idstring = re.sub(r'\s', "_", f'{idstring}') | |
835 | # Remove everything that is not a hyphen or a member of \w |
|
835 | # Remove everything that is not a hyphen or a member of \w |
@@ -1038,33 +1038,71 b' def gravatar_with_user(request, author, ' | |||||
1038 | return _render('gravatar_with_user', author, show_disabled=show_disabled, tooltip=tooltip) |
|
1038 | return _render('gravatar_with_user', author, show_disabled=show_disabled, tooltip=tooltip) | |
1039 |
|
1039 | |||
1040 |
|
1040 | |||
1041 |
tags_paterns = OrderedDict( |
|
1041 | tags_patterns = OrderedDict( | |
1042 | ('lang', (re.compile(r'\[(lang|language)\ \=\>\ *([a-zA-Z\-\/\#\+\.]*)\]'), |
|
1042 | ( | |
1043 | '<div class="metatag" tag="lang">\\2</div>')), |
|
1043 | ( | |
1044 |
|
1044 | "lang", | ||
1045 | ('see', (re.compile(r'\[see\ \=\>\ *([a-zA-Z0-9\/\=\?\&\ \:\/\.\-]*)\]'), |
|
1045 | ( | |
1046 | '<div class="metatag" tag="see">see: \\1 </div>')), |
|
1046 | re.compile(r"\[(lang|language)\ \=\>\ *([a-zA-Z\-\/\#\+\.]*)\]"), | |
1047 |
|
1047 | '<div class="metatag" tag="lang">\\2</div>', | ||
1048 | ('url', (re.compile(r'\[url\ \=\>\ \[([a-zA-Z0-9\ \.\-\_]+)\]\((http://|https://|/)(.*?)\)\]'), |
|
1048 | ), | |
1049 | '<div class="metatag" tag="url"> <a href="\\2\\3">\\1</a> </div>')), |
|
1049 | ), | |
1050 |
|
1050 | ( | ||
1051 | ('license', (re.compile(r'\[license\ \=\>\ *([a-zA-Z0-9\/\=\?\&\ \:\/\.\-]*)\]'), |
|
1051 | "see", | |
1052 | '<div class="metatag" tag="license"><a href="http:\/\/www.opensource.org/licenses/\\1">\\1</a></div>')), |
|
1052 | ( | |
1053 |
|
1053 | re.compile(r"\[see\ \=\>\ *([a-zA-Z0-9\/\=\?\&\ \:\/\.\-]*)\]"), | ||
1054 | ('ref', (re.compile(r'\[(requires|recommends|conflicts|base)\ \=\>\ *([a-zA-Z0-9\-\/]*)\]'), |
|
1054 | '<div class="metatag" tag="see">see: \\1 </div>', | |
1055 | '<div class="metatag" tag="ref \\1">\\1: <a href="/\\2">\\2</a></div>')), |
|
1055 | ), | |
1056 |
|
1056 | ), | ||
1057 | ('state', (re.compile(r'\[(stable|featured|stale|dead|dev|deprecated)\]'), |
|
1057 | ( | |
1058 | '<div class="metatag" tag="state \\1">\\1</div>')), |
|
1058 | "url", | |
1059 |
|
1059 | ( | ||
|
1060 | re.compile( | |||
|
1061 | r"\[url\ \=\>\ \[([a-zA-Z0-9\ \.\-\_]+)\]\((http://|https://|/)(.*?)\)\]" | |||
|
1062 | ), | |||
|
1063 | '<div class="metatag" tag="url"> <a href="\\2\\3">\\1</a> </div>', | |||
|
1064 | ), | |||
|
1065 | ), | |||
|
1066 | ( | |||
|
1067 | "license", | |||
|
1068 | ( | |||
|
1069 | re.compile( | |||
|
1070 | r"\[license\ \=\>\ *([a-zA-Z0-9\/\=\?\&\ \:\/\.\-]*)\]" | |||
|
1071 | ), | |||
|
1072 | r'<div class="metatag" tag="license"><a href="http:\/\/www.opensource.org/licenses/\\1">\\1</a></div>', | |||
|
1073 | ), | |||
|
1074 | ), | |||
|
1075 | ( | |||
|
1076 | "ref", | |||
|
1077 | ( | |||
|
1078 | re.compile( | |||
|
1079 | r"\[(requires|recommends|conflicts|base)\ \=\>\ *([a-zA-Z0-9\-\/]*)\]" | |||
|
1080 | ), | |||
|
1081 | '<div class="metatag" tag="ref \\1">\\1: <a href="/\\2">\\2</a></div>', | |||
|
1082 | ), | |||
|
1083 | ), | |||
|
1084 | ( | |||
|
1085 | "state", | |||
|
1086 | ( | |||
|
1087 | re.compile(r"\[(stable|featured|stale|dead|dev|deprecated)\]"), | |||
|
1088 | '<div class="metatag" tag="state \\1">\\1</div>', | |||
|
1089 | ), | |||
|
1090 | ), | |||
1060 | # label in grey |
|
1091 | # label in grey | |
1061 | ('label', (re.compile(r'\[([a-z]+)\]'), |
|
1092 | ( | |
1062 | '<div class="metatag" tag="label">\\1</div>')), |
|
1093 | "label", | |
1063 |
|
1094 | (re.compile(r"\[([a-z]+)\]"), '<div class="metatag" tag="label">\\1</div>'), | ||
|
1095 | ), | |||
1064 | # generic catch all in grey |
|
1096 | # generic catch all in grey | |
1065 | ('generic', (re.compile(r'\[([a-zA-Z0-9\.\-\_]+)\]'), |
|
1097 | ( | |
1066 | '<div class="metatag" tag="generic">\\1</div>')), |
|
1098 | "generic", | |
1067 | )) |
|
1099 | ( | |
|
1100 | re.compile(r"\[([a-zA-Z0-9\.\-\_]+)\]"), | |||
|
1101 | '<div class="metatag" tag="generic">\\1</div>', | |||
|
1102 | ), | |||
|
1103 | ), | |||
|
1104 | ) | |||
|
1105 | ) | |||
1068 |
|
1106 | |||
1069 |
|
1107 | |||
1070 | def extract_metatags(value): |
|
1108 | def extract_metatags(value): | |
@@ -1075,7 +1113,7 b' def extract_metatags(value):' | |||||
1075 | if not value: |
|
1113 | if not value: | |
1076 | return tags, '' |
|
1114 | return tags, '' | |
1077 |
|
1115 | |||
1078 | for key, val in list(tags_paterns.items()): |
|
1116 | for key, val in list(tags_patterns.items()): | |
1079 | pat, replace_html = val |
|
1117 | pat, replace_html = val | |
1080 | tags.extend([(key, x.group()) for x in pat.finditer(value)]) |
|
1118 | tags.extend([(key, x.group()) for x in pat.finditer(value)]) | |
1081 | value = pat.sub('', value) |
|
1119 | value = pat.sub('', value) | |
@@ -1091,7 +1129,7 b' def style_metatag(tag_type, value):' | |||||
1091 | return '' |
|
1129 | return '' | |
1092 |
|
1130 | |||
1093 | html_value = value |
|
1131 | html_value = value | |
1094 | tag_data = tags_paterns.get(tag_type) |
|
1132 | tag_data = tags_patterns.get(tag_type) | |
1095 | if tag_data: |
|
1133 | if tag_data: | |
1096 | pat, replace_html = tag_data |
|
1134 | pat, replace_html = tag_data | |
1097 | # convert to plain `str` instead of a markup tag to be used in |
|
1135 | # convert to plain `str` instead of a markup tag to be used in | |
@@ -1530,7 +1568,7 b' def urlify_text(text_, safe=True, **href' | |||||
1530 | """ |
|
1568 | """ | |
1531 |
|
1569 | |||
1532 | url_pat = re.compile(r'''(http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@#.&+]''' |
|
1570 | url_pat = re.compile(r'''(http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@#.&+]''' | |
1533 | '''|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+)''') |
|
1571 | r'''|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+)''') | |
1534 |
|
1572 | |||
1535 | def url_func(match_obj): |
|
1573 | def url_func(match_obj): | |
1536 | url_full = match_obj.groups()[0] |
|
1574 | url_full = match_obj.groups()[0] |
@@ -148,7 +148,7 b' def normalize_text_for_matching(x):' | |||||
148 | Replaces all non alfanum characters to spaces and lower cases the string, |
|
148 | Replaces all non alfanum characters to spaces and lower cases the string, | |
149 | useful for comparing two text strings without punctuation |
|
149 | useful for comparing two text strings without punctuation | |
150 | """ |
|
150 | """ | |
151 |
return re.sub(r' |
|
151 | return re.sub(r'\W', ' ', x.lower()) | |
152 |
|
152 | |||
153 |
|
153 | |||
154 | def get_matching_line_offsets(lines, terms=None, markers=None): |
|
154 | def get_matching_line_offsets(lines, terms=None, markers=None): |
@@ -28,14 +28,14 b' from rhodecode.tests import no_newline_i' | |||||
28 |
|
28 | |||
29 |
|
29 | |||
30 | @pytest.mark.parametrize('url, expected_url', [ |
|
30 | @pytest.mark.parametrize('url, expected_url', [ | |
31 | ('http://rc.com', '<a href="http://rc.com">http://rc.com</a>'), |
|
31 | (r'https://rc.com', '<a href="https://rc.com">http://rc.com</a>'), | |
32 | ('http://rc.com/test', '<a href="http://rc.com/test">http://rc.com/test</a>'), |
|
32 | (r'https://rc.com/test', '<a href="https://rc.com/test">https://rc.com/test</a>'), | |
33 | ('http://rc.com/!foo', '<a href="http://rc.com/!foo">http://rc.com/!foo</a>'), |
|
33 | (r'https://rc.com/!foo', '<a href="https://rc.com/!foo">https://rc.com/!foo</a>'), | |
34 | ('http://rc.com/&foo', '<a href="http://rc.com/&foo">http://rc.com/&foo</a>'), |
|
34 | (r'https://rc.com/&foo', '<a href="https://rc.com/&foo">https://rc.com/&foo</a>'), | |
35 | ('http://rc.com/?foo-1&bar=1', '<a href="http://rc.com/?foo-1&bar=1">http://rc.com/?foo-1&bar=1</a>'), |
|
35 | (r'https://rc.com/?foo-1&bar=1', '<a href="https://rc.com/?foo-1&bar=1">https://rc.com/?foo-1&bar=1</a>'), | |
36 | ('http://rc.com?foo-1&bar=1', '<a href="http://rc.com?foo-1&bar=1">http://rc.com?foo-1&bar=1</a>'), |
|
36 | (r'https://rc.com?foo-1&bar=1', '<a href="https://rc.com?foo-1&bar=1">https://rc.com?foo-1&bar=1</a>'), | |
37 | ('http://rc.com/#foo', '<a href="http://rc.com/#foo">http://rc.com/#foo</a>'), |
|
37 | (r'https://rc.com/#foo', '<a href="https://rc.com/#foo">https://rc.com/#foo</a>'), | |
38 | ('http://rc.com/@foo', '<a href="http://rc.com/@foo">http://rc.com/@foo</a>'), |
|
38 | (r'https://rc.com/@foo', '<a href="https://rc.com/@foo">https://rc.com/@foo</a>'), | |
39 | ]) |
|
39 | ]) | |
40 | def test_urlify_text(url, expected_url): |
|
40 | def test_urlify_text(url, expected_url): | |
41 | assert helpers.urlify_text(url) == expected_url |
|
41 | assert helpers.urlify_text(url) == expected_url | |
@@ -95,12 +95,12 b' def test_format_binary():' | |||||
95 |
|
95 | |||
96 |
|
96 | |||
97 | @pytest.mark.parametrize('text_string, pattern, expected', [ |
|
97 | @pytest.mark.parametrize('text_string, pattern, expected', [ | |
98 | ('No issue here', '(?:#)(?P<issue_id>\d+)', []), |
|
98 | ('No issue here', r'(?:#)(?P<issue_id>\d+)', []), | |
99 | ('Fix #42', '(?:#)(?P<issue_id>\d+)', |
|
99 | ('Fix #42', '(?:#)(?P<issue_id>\d+)', | |
100 | [{'url': 'http://r.io/{repo}/i/42', 'id': '42'}]), |
|
100 | [{'url': 'https://r.io/{repo}/i/42', 'id': '42'}]), | |
101 | ('Fix #42, #53', '(?:#)(?P<issue_id>\d+)', [ |
|
101 | ('Fix #42, #53', '(?:#)(?P<issue_id>\d+)', [ | |
102 | {'url': 'http://r.io/{repo}/i/42', 'id': '42'}, |
|
102 | {'url': 'https://r.io/{repo}/i/42', 'id': '42'}, | |
103 | {'url': 'http://r.io/{repo}/i/53', 'id': '53'}]), |
|
103 | {'url': 'https://r.io/{repo}/i/53', 'id': '53'}]), | |
104 | ('Fix #42', '(?:#)?<issue_id>\d+)', []), # Broken regex |
|
104 | ('Fix #42', '(?:#)?<issue_id>\d+)', []), # Broken regex | |
105 | ]) |
|
105 | ]) | |
106 | def test_extract_issues(backend, text_string, pattern, expected): |
|
106 | def test_extract_issues(backend, text_string, pattern, expected): | |
@@ -109,7 +109,7 b' def test_extract_issues(backend, text_st' | |||||
109 | '123': { |
|
109 | '123': { | |
110 | 'uid': '123', |
|
110 | 'uid': '123', | |
111 | 'pat': pattern, |
|
111 | 'pat': pattern, | |
112 | 'url': 'http://r.io/${repo}/i/${issue_id}', |
|
112 | 'url': r'https://r.io/${repo}/i/${issue_id}', | |
113 | 'pref': '#', |
|
113 | 'pref': '#', | |
114 | 'desc': 'Test Pattern' |
|
114 | 'desc': 'Test Pattern' | |
115 | } |
|
115 | } |
@@ -36,29 +36,29 b' class TestGroupNameType(object):' | |||||
36 | assert result == expected |
|
36 | assert result == expected | |
37 |
|
37 | |||
38 | @pytest.mark.parametrize('given, expected', [ |
|
38 | @pytest.mark.parametrize('given, expected', [ | |
39 | ('//group1/group2//', 'group1/group2'), |
|
39 | (r'//group1/group2//', 'group1/group2'), | |
40 | ('//group1///group2//', 'group1/group2'), |
|
40 | (r'//group1///group2//', 'group1/group2'), | |
41 | ('group1/group2///group3', 'group1/group2/group3'), |
|
41 | (r'group1/group2///group3', 'group1/group2/group3'), | |
42 | ('v1.2', 'v1.2'), |
|
42 | (r'v1.2', 'v1.2'), | |
43 | ('/v1.2', 'v1.2'), |
|
43 | (r'/v1.2', 'v1.2'), | |
44 | ('.dirs', '.dirs'), |
|
44 | (r'.dirs', '.dirs'), | |
45 | ('..dirs', '.dirs'), |
|
45 | (r'..dirs', '.dirs'), | |
46 | ('./..dirs', '.dirs'), |
|
46 | (r'./..dirs', '.dirs'), | |
47 | ('dir/;name;/;[];/sub', 'dir/name/sub'), |
|
47 | (r'dir/;name;/;[];/sub', 'dir/name/sub'), | |
48 | (',/,/,d,,,', 'd'), |
|
48 | (r',/,/,d,,,', 'd'), | |
49 | ('/;/#/,d,,,', 'd'), |
|
49 | (r'/;/#/,d,,,', 'd'), | |
50 | ('long../../..name', 'long./.name'), |
|
50 | (r'long../../..name', 'long./.name'), | |
51 | ('long../..name', 'long./.name'), |
|
51 | (r'long../..name', 'long./.name'), | |
52 | ('../', ''), |
|
52 | (r'../', ''), | |
53 | ('\'../"../', ''), |
|
53 | (r'\'../"../', ''), | |
54 | ('c,/,/..//./,c,,,/.d/../.........c', 'c/c/.d/.c'), |
|
54 | (r'c,/,/..//./,c,,,/.d/../.........c', 'c/c/.d/.c'), | |
55 | ('c,/,/..//./,c,,,', 'c/c'), |
|
55 | (r'c,/,/..//./,c,,,', 'c/c'), | |
56 | ('d../..d', 'd./.d'), |
|
56 | (r'd../..d', 'd./.d'), | |
57 | ('d../../d', 'd./d'), |
|
57 | (r'd../../d', 'd./d'), | |
58 |
|
58 | |||
59 | ('d\;\./\,\./d', 'd./d'), |
|
59 | (r'd\;\./\,\./d', 'd./d'), | |
60 | ('d\.\./\.\./d', 'd./d'), |
|
60 | (r'd\.\./\.\./d', 'd./d'), | |
61 | ('d\.\./\..\../d', 'd./d'), |
|
61 | (r'd\.\./\..\../d', 'd./d'), | |
62 | ]) |
|
62 | ]) | |
63 | def test_deserialize_clean_up_name(self, given, expected): |
|
63 | def test_deserialize_clean_up_name(self, given, expected): | |
64 | class TestSchema(colander.Schema): |
|
64 | class TestSchema(colander.Schema): |
General Comments 0
You need to be logged in to leave comments.
Login now