Author: svn-role
Date: Mon Jul 6 04:00:10 2026
New Revision: 1935921
Log:
Merge r1927953 from trunk:
* r1927953
On Windows, use the WC_NO_BEST_FIT_CHARS flag when converting individual
command-line arguments to the ANSI code page
Justification:
Fixes a bug with incorrect interpretation of some individual Unicode
command-line arguments.
Notes:
This is an interim fix. A long-term solution is to convert arguments
to UTF-8 and work with UTF-8 directly, but until then failing fast
should be better than changing the user input.
Votes:
+1: kotkov, rinrab, ivan
Modified:
subversion/branches/1.14.x/ (props changed)
subversion/branches/1.14.x/STATUS
subversion/branches/1.14.x/subversion/libsvn_subr/cmdline.c
subversion/branches/1.14.x/subversion/tests/cmdline/basic_tests.py
Modified: subversion/branches/1.14.x/STATUS
==============================================================================
--- subversion/branches/1.14.x/STATUS Sun Jul 5 23:22:24 2026
(r1935920)
+++ subversion/branches/1.14.x/STATUS Mon Jul 6 04:00:10 2026
(r1935921)
@@ -88,16 +88,3 @@ Veto-blocked changes:
Approved changes:
=================
-
- * r1927953
- On Windows, use the WC_NO_BEST_FIT_CHARS flag when converting individual
- command-line arguments to the ANSI code page
- Justification:
- Fixes a bug with incorrect interpretation of some individual Unicode
- command-line arguments.
- Notes:
- This is an interim fix. A long-term solution is to convert arguments
- to UTF-8 and work with UTF-8 directly, but until then failing fast
- should be better than changing the user input.
- Votes:
- +1: kotkov, rinrab, ivan
Modified: subversion/branches/1.14.x/subversion/libsvn_subr/cmdline.c
==============================================================================
--- subversion/branches/1.14.x/subversion/libsvn_subr/cmdline.c Sun Jul 5
23:22:24 2026 (r1935920)
+++ subversion/branches/1.14.x/subversion/libsvn_subr/cmdline.c Mon Jul 6
04:00:10 2026 (r1935921)
@@ -1917,23 +1917,36 @@ svn_cmdline__win32_get_cstring_argv(cons
const wchar_t *arg = argv[i];
char *cstring_arg;
int rv;
+ BOOL used_default_char;
/* Passing -1 for the string length guarantees that the returned length
will account for a terminating null character. */
- rv = WideCharToMultiByte(CP_ACP, 0, arg, -1, NULL, 0, NULL, NULL);
+ rv = WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, arg, -1,
+ NULL, 0, NULL, &used_default_char);
if (rv <= 0)
{
return svn_error_wrap_apr(apr_get_os_error(),
_("Conversion from UTF-16 failed"));
}
+ else if (used_default_char)
+ {
+ return
svn_error_wrap_apr(APR_FROM_OS_ERROR(ERROR_NO_UNICODE_TRANSLATION),
+ _("Conversion from UTF-16 failed"));
+ }
cstring_arg = apr_palloc(result_pool, rv);
- rv = WideCharToMultiByte(CP_ACP, 0, arg, -1, cstring_arg, rv, NULL,
NULL);
+ rv = WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, arg, -1,
+ cstring_arg, rv, NULL, &used_default_char);
if (rv <= 0)
{
return svn_error_wrap_apr(apr_get_os_error(),
_("Conversion from UTF-16 failed"));
}
+ else if (used_default_char)
+ {
+ return
svn_error_wrap_apr(APR_FROM_OS_ERROR(ERROR_NO_UNICODE_TRANSLATION),
+ _("Conversion from UTF-16 failed"));
+ }
APR_ARRAY_PUSH(cstring_argv, const char *) = cstring_arg;
}
Modified: subversion/branches/1.14.x/subversion/tests/cmdline/basic_tests.py
==============================================================================
--- subversion/branches/1.14.x/subversion/tests/cmdline/basic_tests.py Sun Jul
5 23:22:24 2026 (r1935920)
+++ subversion/branches/1.14.x/subversion/tests/cmdline/basic_tests.py Mon Jul
6 04:00:10 2026 (r1935921)
@@ -3279,19 +3279,20 @@ def argv_with_best_fit_chars(sbox):
yield chr(c), mbcs
count = 0
- expected_stderr = svntest.verify.RegexListOutput(
- [r'^"foo.+bar": unknown command\.\n$', '\n'], match_all=True)
+ # E721113: Conversion from UTF-16 failed: No mapping for the Unicode
+ # character exists in the target multi-byte code page.
+ expected_stderr = 'svn: E721113: '
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',
+ svntest.actions.run_and_verify_svn2(None, expected_stderr, 1, 'help',
'foo{0} {0}bar'.format(wc))
elif mbcs == b'\\':
- svntest.actions.run_and_verify_svn2(None, expected_stderr, 0, 'help',
+ svntest.actions.run_and_verify_svn2(None, expected_stderr, 1, 'help',
'foo{0}" {0}"bar'.format(wc))
elif mbcs == b' ':
- svntest.actions.run_and_verify_svn2(None, expected_stderr, 0, 'help',
+ svntest.actions.run_and_verify_svn2(None, expected_stderr, 1, 'help',
'foo{0}bar'.format(wc))
if count == 0:
raise svntest.Skip('No best fit characters in code page %r' % codepage)