Author: svn-role Date: Sat Jan 30 04:00:48 2021 New Revision: 1886042 URL: http://svn.apache.org/viewvc?rev=1886042&view=rev Log: Merge r1885953 from trunk:
* r1885953 Fix file name encoding and quoting when invoking editor on Windows. Justification: Invoking editor with special character or spaces in path is broken on Windows. Depends: r1882234 Votes: +1: jcorvel, futatuki, stsp Modified: subversion/branches/1.14.x/ (props changed) subversion/branches/1.14.x/STATUS subversion/branches/1.14.x/subversion/libsvn_subr/cmdline.c Propchange: subversion/branches/1.14.x/ ------------------------------------------------------------------------------ Merged /subversion/trunk:r1885953 Modified: subversion/branches/1.14.x/STATUS URL: http://svn.apache.org/viewvc/subversion/branches/1.14.x/STATUS?rev=1886042&r1=1886041&r2=1886042&view=diff ============================================================================== --- subversion/branches/1.14.x/STATUS (original) +++ subversion/branches/1.14.x/STATUS Sat Jan 30 04:00:48 2021 @@ -67,16 +67,6 @@ Veto-blocked changes: Approved changes: ================= - * r1885953 - Fix file name encoding and quoting when invoking editor on Windows. - Justification: - Invoking editor with special character or spaces in path is broken - on Windows. - Depends: - r1882234 - Votes: - +1: jcorvel, futatuki, stsp - * r1886019 Fix a potential NULL dereference in the config file parser. Justification: Modified: subversion/branches/1.14.x/subversion/libsvn_subr/cmdline.c URL: http://svn.apache.org/viewvc/subversion/branches/1.14.x/subversion/libsvn_subr/cmdline.c?rev=1886042&r1=1886041&r2=1886042&view=diff ============================================================================== --- subversion/branches/1.14.x/subversion/libsvn_subr/cmdline.c (original) +++ subversion/branches/1.14.x/subversion/libsvn_subr/cmdline.c Sat Jan 30 04:00:48 2021 @@ -47,6 +47,7 @@ #endif #include <apr_general.h> /* for apr_initialize/apr_terminate */ #include <apr_strings.h> /* for apr_snprintf */ +#include <apr_env.h> /* for apr_env_get */ #include <apr_pools.h> #include <apr_signal.h> @@ -1240,38 +1241,84 @@ svn_cmdline__be_interactive(svn_boolean_ /* Helper for the edit_externally functions. Set *EDITOR to some path to an - editor binary. Sources to search include: the EDITOR_CMD argument - (if not NULL), $SVN_EDITOR, the runtime CONFIG variable (if CONFIG + editor binary, in native C string on Unix/Linux platforms and in UTF-8 + string on Windows platform. Sources to search include: the EDITOR_CMD + argument (if not NULL), $SVN_EDITOR, the runtime CONFIG variable (if CONFIG is not NULL), $VISUAL, $EDITOR. Return SVN_ERR_CL_NO_EXTERNAL_EDITOR if no binary can be found. */ static svn_error_t * find_editor_binary(const char **editor, const char *editor_cmd, - apr_hash_t *config) + apr_hash_t *config, + apr_pool_t *pool) { const char *e; + const char *e_cfg; struct svn_config_t *cfg; + apr_status_t status; /* Use the editor specified on the command line via --editor-cmd, if any. */ +#ifdef WIN32 + /* On Windows, editor_cmd is transcoded to the system active code page + because we use main() as a entry point without APR's (or our own) wrapper + in command line tools. */ + if (editor_cmd) + { + SVN_ERR(svn_utf_cstring_to_utf8(&e, editor_cmd, pool)); + } + else + { + e = NULL; + } +#else e = editor_cmd; +#endif /* Otherwise look for the Subversion-specific environment variable. */ if (! e) - e = getenv("SVN_EDITOR"); + { + status = apr_env_get((char **)&e, "SVN_EDITOR", pool); + if (status || ! *e) + { + e = NULL; + } + } /* If not found then fall back on the config file. */ if (! e) { cfg = config ? svn_hash_gets(config, SVN_CONFIG_CATEGORY_CONFIG) : NULL; - svn_config_get(cfg, &e, SVN_CONFIG_SECTION_HELPERS, + svn_config_get(cfg, &e_cfg, SVN_CONFIG_SECTION_HELPERS, SVN_CONFIG_OPTION_EDITOR_CMD, NULL); +#ifdef WIN32 + if (e_cfg) + { + /* On Windows, we assume that config values are set in system active + code page, so we need transcode it here. */ + SVN_ERR(svn_utf_cstring_to_utf8(&e, e_cfg, pool)); + } +#else + e = e_cfg; +#endif } /* If not found yet then try general purpose environment variables. */ if (! e) - e = getenv("VISUAL"); + { + status = apr_env_get((char**)&e, "VISUAL", pool); + if (status || ! *e) + { + e = NULL; + } + } if (! e) - e = getenv("EDITOR"); + { + status = apr_env_get((char**)&e, "EDITOR", pool); + if (status || ! *e) + { + e = NULL; + } + } #ifdef SVN_CLIENT_EDITOR /* If still not found then fall back on the hard-coded default. */ @@ -1406,13 +1453,16 @@ svn_cmdline__edit_file_externally(const { const char *editor, *cmd, *base_dir, *file_name, *base_dir_apr; const char *file_name_local; +#ifdef WIN32 + const WCHAR *wcmd; +#endif char *old_cwd; int sys_err; apr_status_t apr_err; svn_dirent_split(&base_dir, &file_name, path, pool); - SVN_ERR(find_editor_binary(&editor, editor_cmd, config)); + SVN_ERR(find_editor_binary(&editor, editor_cmd, config, pool)); apr_err = apr_filepath_get(&old_cwd, APR_FILEPATH_NATIVE, pool); if (apr_err) @@ -1433,8 +1483,14 @@ svn_cmdline__edit_file_externally(const escape_path(pool, file_name), pool)); /* editor is explicitly documented as being interpreted by the user's shell, and as such should already be quoted/escaped as needed. */ +#ifndef WIN32 cmd = apr_psprintf(pool, "%s %s", editor, file_name_local); sys_err = system(cmd); +#else + cmd = apr_psprintf(pool, "\"%s %s\"", editor, file_name_local); + SVN_ERR(svn_utf__win32_utf8_to_utf16(&wcmd, cmd, NULL, pool)); + sys_err = _wsystem(wcmd); +#endif apr_err = apr_filepath_set(old_cwd, pool); if (apr_err) @@ -1466,6 +1522,9 @@ svn_cmdline__edit_string_externally(svn_ { const char *editor; const char *cmd; +#ifdef WIN32 + const WCHAR *wcmd; +#endif apr_file_t *tmp_file; const char *tmpfile_name; const char *tmpfile_native; @@ -1479,7 +1538,7 @@ svn_cmdline__edit_string_externally(svn_ int sys_err; svn_boolean_t remove_file = TRUE; - SVN_ERR(find_editor_binary(&editor, editor_cmd, config)); + SVN_ERR(find_editor_binary(&editor, editor_cmd, config, pool)); /* Convert file contents from UTF-8/LF if desired. */ if (as_text) @@ -1596,7 +1655,11 @@ svn_cmdline__edit_string_externally(svn_ /* editor is explicitly documented as being interpreted by the user's shell, and as such should already be quoted/escaped as needed. */ +#ifndef WIN32 cmd = apr_psprintf(pool, "%s %s", editor, tmpfile_native); +#else + cmd = apr_psprintf(pool, "\"%s %s\"", editor, tmpfile_native); +#endif /* If the caller wants us to leave the file around, return the path of the file we'll use, and make a note not to destroy it. */ @@ -1607,7 +1670,12 @@ svn_cmdline__edit_string_externally(svn_ } /* Now, run the editor command line. */ +#ifndef WIN32 sys_err = system(cmd); +#else + SVN_ERR(svn_utf__win32_utf8_to_utf16(&wcmd, cmd, NULL, pool)); + sys_err = _wsystem(wcmd); +#endif if (sys_err != 0) { /* Extracting any meaning from sys_err is platform specific, so just