Author: jun66j5
Date: Thu Oct 17 03:00:43 2024
New Revision: 1921371
URL: http://svn.apache.org/viewvc?rev=1921371&view=rev
Log:
Add regression tests for CVE-2024-45720 (Subversion command line argument
injection on Windows platforms).
* subversion/tests/cmdline/basic_tests.py
(argv_with_best_fit_chars): Added
Modified:
subversion/trunk/subversion/tests/cmdline/basic_tests.py
Modified: subversion/trunk/subversion/tests/cmdline/basic_tests.py
URL:
http://svn.apache.org/viewvc/subversion/trunk/subversion/tests/cmdline/basic_tests.py?rev=1921371&r1=1921370&r2=1921371&view=diff
==============================================================================
--- subversion/trunk/subversion/tests/cmdline/basic_tests.py (original)
+++ subversion/trunk/subversion/tests/cmdline/basic_tests.py Thu Oct 17
03:00:43 2024
@@ -3293,6 +3293,60 @@ def keep_local_reverted_properly(sbox):
svntest.actions.run_and_verify_status(wc_dir, expected_output)
+@SkipUnless(svntest.main.is_os_windows)
+def argv_with_best_fit_chars(sbox):
+ """argv with best fit chars"""
+
+ import ctypes
+ from ctypes import windll, wintypes
+
+ CP_ACP = 0
+ kernel32 = windll.kernel32
+ WideCharToMultiByte = kernel32.WideCharToMultiByte
+ WideCharToMultiByte.argtypes = [
+ wintypes.UINT, wintypes.DWORD, wintypes.LPCWSTR, ctypes.c_int,
+ wintypes.LPSTR, ctypes.c_int, wintypes.LPCSTR, wintypes.LPBOOL,
+ ]
+ WideCharToMultiByte.restype = ctypes.c_int
+ codepage = kernel32.GetACP()
+
+ def regexlines(*patterns):
+ return svntest.verify.RegexListOutput(list(patterns), match_all=True)
+
+ def iter_bestfit_chars():
+ chars = {b'"': 0, b'\\': 0, b' ': 0}
+ for c in range(0x80, 0x10000):
+ wcs = ctypes.create_unicode_buffer(chr(c))
+ mbcs = ctypes.create_string_buffer(8)
+ rc = WideCharToMultiByte(CP_ACP, 0, wcs, len(wcs), mbcs, len(mbcs), None,
+ None)
+ if rc == 0:
+ continue
+ mbcs = mbcs.value
+ if chars.get(mbcs) != 0:
+ continue
+ chars[mbcs] = c
+ yield chr(c), mbcs
+
+ count = 0
+ expected_stderr = svntest.verify.RegexListOutput(
+ [r'^"foo.+bar": unknown command\.\n$', '\n'], match_all=True)
+ for wc, mbcs in iter_bestfit_chars():
+ count += 1
+ logger.info('Code page %r - U+%04x -> 0x%s', codepage, ord(wc), mbcs.hex())
+ if mbcs == b'"':
+ svntest.actions.run_and_verify_svn2(None, expected_stderr, 0, 'help',
+ 'foo{0} {0}bar'.format(wc))
+ elif mbcs == b'\\':
+ svntest.actions.run_and_verify_svn2(None, expected_stderr, 0, 'help',
+ 'foo{0}" {0}"bar'.format(wc))
+ elif mbcs == b' ':
+ svntest.actions.run_and_verify_svn2(None, expected_stderr, 0, 'help',
+ 'foo{0}bar'.format(wc))
+ if count == 0:
+ raise svntest.Skip('No best fit characters in code page %r' % codepage)
+
+
########################################################################
# Run the tests
@@ -3369,6 +3423,7 @@ test_list = [ None,
null_prop_update_last_changed_revision,
filtered_ls_top_level_path,
keep_local_reverted_properly,
+ argv_with_best_fit_chars,
]
if __name__ == '__main__':