Skip to content

Commit cf21822

Browse files
committed
Merge remote-tracking branch 'origin/master' into edge
2 parents e2f6d7c + bffa3fd commit cf21822

File tree

2 files changed

+72
-6
lines changed

2 files changed

+72
-6
lines changed

mig/shared/safeinput.py

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@
3838
from __future__ import print_function
3939
from __future__ import absolute_import
4040

41-
import cgi
4241
import re
42+
import sys
4343
from email.utils import parseaddr, formataddr
4444
from string import ascii_letters, digits, printable
4545
from unicodedata import category, normalize, name as unicode_name
@@ -49,6 +49,15 @@
4949
except ImportError:
5050
nbformat = None
5151

52+
PY2 = sys.version_info[0] < 3
53+
54+
escape_html = None
55+
if PY2:
56+
from cgi import escape as escape_html
57+
else:
58+
from html import escape as escape_html
59+
assert escape_html is not None
60+
5261
from mig.shared.base import force_unicode, force_utf8
5362
from mig.shared.defaults import src_dst_sep, username_charset, \
5463
username_max_length, session_id_charset, session_id_length, \
@@ -319,16 +328,18 @@ def __wrap_unicode_val(char):
319328

320329
# Public functions
321330

322-
def html_escape(contents):
323-
"""Uses cgi.escape() to encode contents in a html safe way. In that
331+
def html_escape(contents, quote=None):
332+
"""Use an stdlib escape to encode contents in a html safe way. In that
324333
way the resulting data can be included in a html page without risk
325334
of XSS vulnerabilities.
335+
The optional quote argument is passed as-is to enable additional escaping
336+
of single and double quotes.
326337
"""
327338

328339
# We use html_escape as a general protection even though it is
329-
# mostly html (cgi) related
340+
# mostly html request related
330341

331-
return cgi.escape(contents)
342+
return escape_html(contents, quote)
332343

333344

334345
def valid_printable(contents, min_length=0, max_length=-1):
@@ -2270,7 +2281,9 @@ def __str__(self):
22702281
return force_utf8(force_unicode(self.value))
22712282

22722283

2273-
if __name__ == '__main__':
2284+
def main(_print=print):
2285+
print = _print # workaround print as reserved word on PY2
2286+
22742287
for test_cn in ('Firstname Lastname', 'Test Æøå', 'Test Überh4x0r',
22752288
'Harry S. Truman', u'Unicode æøå', "Invalid D'Angelo",
22762289
'Test Maybe Invalid Źacãŕ', 'Test Invalid ?',
@@ -2468,3 +2481,6 @@ def __str__(self):
24682481
print("Rejected:")
24692482
for (key, val) in rejected.items():
24702483
print("\t%s: %s" % (key, val))
2484+
2485+
if __name__ == '__main__':
2486+
main()

tests/test_mig_shared_safeinput.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# -*- coding: utf-8 -*-
2+
#
3+
# --- BEGIN_HEADER ---
4+
#
5+
# addheader - add license header to all code modules.
6+
# Copyright (C) 2003-2024 The MiG Project by the Science HPC Center at UCPH
7+
#
8+
# This file is part of MiG.
9+
#
10+
# MiG is free software: you can redistribute it and/or modify
11+
# it under the terms of the GNU General Public License as published by
12+
# the Free Software Foundation; either version 2 of the License, or
13+
# (at your option) any later version.
14+
#
15+
# MiG is distributed in the hope that it will be useful,
16+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
17+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18+
# GNU General Public License for more details.
19+
#
20+
# You should have received a copy of the GNU General Public License
21+
# along with this program; if not, write to the Free Software
22+
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
23+
# USA.
24+
#
25+
# --- END_HEADER ---
26+
#
27+
28+
"""Unit tests for the migrid module pointed to in the filename"""
29+
30+
import importlib
31+
import os
32+
import sys
33+
34+
sys.path.append(os.path.realpath(os.path.join(os.path.dirname(__file__), ".")))
35+
36+
from support import MigTestCase, testmain
37+
38+
39+
class MigSharedSafeinput(MigTestCase):
40+
41+
def test_basic_import(self):
42+
safeimport = importlib.import_module("mig.shared.safeinput")
43+
44+
def test_existing_main(self):
45+
safeimport = importlib.import_module("mig.shared.safeinput")
46+
safeimport.main(_print=lambda _: None)
47+
48+
49+
if __name__ == '__main__':
50+
testmain()

0 commit comments

Comments
 (0)