jamessan_at_apache.org wrote on Sat, 15 Feb 2020 16:24 -0000:
> Escape filenames when invoking $SVN_EDITOR
>
> Per https://subversion.apache.org/faq.html#svn-editor, $SVN_EDITOR is invoked
> through the shell instead of directly executed. The user is expected to
> properly escape/quote $SVN_EDITOR, but svn was putting the filename directly
> into the command without any escaping. This therefore breaks attempts to,
> e.g., run the editor from the merge conflict dialog when a path has special
> characters.
>
> Update locations where we invoke the editor to quote the filename as well as
> escape shell special characters using apr_pescape_shell(). The quotes are
> needed in addition to the escaping, since apr_pescape_shell() does not escape
> whitespace.
> +++ subversion/trunk/subversion/libsvn_subr/cmdline.c Sat Feb 15 16:24:53 2020
> @@ -1330,7 +1331,10 @@ svn_cmdline__edit_file_externally(const
> return svn_error_wrap_apr
> (apr_err, _("Can't change working directory to '%s'"), base_dir);
>
> - cmd = apr_psprintf(pool, "%s %s", editor, file_name);
> + /* editor is explicitly documented as being interpreted by the user's shell,
> + and as such should already be quoted/escaped as needed. */
> + cmd = apr_psprintf(pool, "%s \"%s\"", editor,
> + apr_pescape_shell(pool, file_name));
If FILE_NAME is «;» (i.e., a single semicolon), apr_pescape_shell()
will return «\;» (two bytes) and then the command string will be «vi "\;"»,
so vi would edit the file «\;» (two bytes).
This can happen in the conflict-callbacks.c caller, which
passes LOCAL_ABSPATH of a versioned file:
[[[
#!/bin/sh
rm -rf r wc
svnadmin create r
svnmucc put -U file://`pwd`/r -m 'r1' /dev/null ';'
svn co -q file://`pwd`/r wc
cd wc
echo foo > ';'
svn ci -q -m 'r2'
svn up -q -r1
echo bar > ';'
../subversion/svn/svn up --accept=e --editor-cmd='false'
]]]
[[[
% ./repro.sh
r1 committed by daniel at 2020-02-15T17:23:47.372055Z
Updating '.':
C ;
Updated to revision 2.
system('false "\;"') returned 256
Merge conflicts in ';' marked as resolved.
Summary of conflicts:
Text conflicts: 0 remaining (and 1 already resolved)
]]]
That could conceivably happen for other callers as well if
svn_io_open_uniquely_named() returns an abspath which contains
a literal semicolon in the directory part. Its API contract
doesn't forbid that.
Sorry for not noticing this before; I'm sure I saw a previous version
of this patch at some point…
Daniel
> sys_err = system(cmd);
>
> apr_err = apr_filepath_set(old_cwd, pool);
> @@ -1489,7 +1493,11 @@ svn_cmdline__edit_string_externally(svn_
> err = svn_utf_cstring_from_utf8(&tmpfile_native, tmpfile_name, pool);
> if (err)
> goto cleanup;
> - cmd = apr_psprintf(pool, "%s %s", editor, tmpfile_native);
> +
> + /* editor is explicitly documented as being interpreted by the user's shell,
> + and as such should already be quoted/escaped as needed. */
> + cmd = apr_psprintf(pool, "%s \"%s\"", editor,
> + apr_pescape_shell(pool, tmpfile_native));
Received on 2020-02-15 18:26:35 CET