svn commit: r1921371 - /subversion/trunk/subversion/tests/cmdline/basic_tests.py

[email protected]
Newsgroups gmane.comp.version-control.subversion.svn
Message-ID <[email protected]>
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__':
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.