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


Reply via email to