subversion-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From julianf...@apache.org
Subject svn commit: r1476461 - in /subversion/trunk/subversion/svn: cl.h svn.c
Date Sat, 27 Apr 2013 01:19:39 GMT
Author: julianfoad
Date: Sat Apr 27 01:19:38 2013
New Revision: 1476461

URL: http://svn.apache.org/r1476461
Log:
Fix non-ASCII character handling in several 'svn' command-line options, when
using a non-UTF-8 locale. In roughly decreasing order of importance:

  --old, --new:
    It did not convert the path to UTF-8. It would fail to find a non-ASCII
    path, or conceivably could find the wrong path.

  --search, --search-and:
    It did not convert the search term to UTF-8. It would fail to match a
    non-ASCII search term, or conceivably could find a wrong match.

  --file:
    The check for accidentally specifying a versioned file used the
    unconverted path, and so a non-ASCII path would (most likely) not
    trigger the check when it should.

  --limit, --accept, --show-revs, --strip, --change:
    It did not convert the value to UTF-8 before parsing it. Valid values
    would work properly, but the error message displayed for an invalid
    value would display the invalid value wrongly.

  --native-eol
    Conversion to UTF-8 has been moved before comparison against fixed ASCII
    strings like 'CRLF'. This will only make a difference if there are
    character encodings in use that are not compatible with ASCII; otherwise
    it is just for consistency of coding style.

* subversion/svn/svn.c
  (sub_main): Convert option arguments to UTF-8 before using them, in most
    cases where we weren't already doing so.

* subversion/svn/cl.h
  (svn_cl__opt_state_t): Document which fields are *not* converted to UTF-8,
    instead of the previous incomplete annotation of which ones are. Remove
    the unused 'changelist' field (which was long ago superseded by the
    'changelists' array.

Modified:
    subversion/trunk/subversion/svn/cl.h
    subversion/trunk/subversion/svn/svn.c

Modified: subversion/trunk/subversion/svn/cl.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/cl.h?rev=1476461&r1=1476460&r2=1476461&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/cl.h (original)
+++ subversion/trunk/subversion/svn/cl.h Sat Apr 27 01:19:38 2013
@@ -158,7 +158,7 @@ typedef struct svn_cl__opt_state_t
   /* Was --no-unlock specified? */
   svn_boolean_t no_unlock;
 
-  const char *message;           /* log message */
+  const char *message;           /* log message (not converted to UTF-8) */
   svn_boolean_t force;           /* be more forceful, as in "svn rm -f ..." */
   svn_boolean_t force_log;       /* force validity of a suspect log msg file */
   svn_boolean_t incremental;     /* yield output suitable for concatenation */
@@ -168,19 +168,22 @@ typedef struct svn_cl__opt_state_t
   svn_boolean_t verbose;         /* be verbose */
   svn_boolean_t update;          /* contact the server for the full story */
   svn_boolean_t strict;          /* do strictly what was requested */
-  svn_stringbuf_t *filedata;     /* contents of file used as option data */
-  const char *encoding;          /* the locale/encoding of the data*/
+  svn_stringbuf_t *filedata;     /* contents of file used as option data
+                                    (not converted to UTF-8) */
+  const char *encoding;          /* the locale/encoding of 'message' and of
+                                    'filedata' (not converted to UTF-8) */
   svn_boolean_t help;            /* print usage message */
-  const char *auth_username;     /* auth username */ /* UTF-8! */
-  const char *auth_password;     /* auth password */ /* UTF-8! */
-  const char *extensions;        /* subprocess extension args */ /* UTF-8! */
-  apr_array_header_t *targets;   /* target list from file */ /* UTF-8! */
+  const char *auth_username;     /* auth username */
+  const char *auth_password;     /* auth password */
+  const char *extensions;        /* subprocess extension args */
+  apr_array_header_t *targets;   /* target list from file */
   svn_boolean_t xml;             /* output in xml, e.g., "svn log --xml" */
   svn_boolean_t no_ignore;       /* disregard default ignores & svn:ignore's */
   svn_boolean_t no_auth_cache;   /* do not cache authentication information */
   struct
     {
-  const char *diff_cmd;              /* the external diff command to use */
+  const char *diff_cmd;              /* the external diff command to use
+                                        (not converted to UTF-8) */
   svn_boolean_t internal_diff;       /* override diff_cmd in config file */
   svn_boolean_t no_diff_added;       /* do not show diffs for deleted files */
   svn_boolean_t no_diff_deleted;     /* do not show diffs for deleted files */
@@ -197,8 +200,10 @@ typedef struct svn_cl__opt_state_t
   svn_boolean_t stop_on_copy;    /* don't cross copies during processing */
   svn_boolean_t dry_run;         /* try operation but make no changes */
   svn_boolean_t revprop;         /* operate on a revision property */
-  const char *merge_cmd;         /* the external merge command to use */
-  const char *editor_cmd;        /* the external editor command to use */
+  const char *merge_cmd;         /* the external merge command to use
+                                    (not converted to UTF-8) */
+  const char *editor_cmd;        /* the external editor command to use
+                                    (not converted to UTF-8) */
   svn_boolean_t record_only;     /* whether to record mergeinfo */
   const char *old_target;        /* diff target */
   const char *new_target;        /* diff target */
@@ -210,13 +215,12 @@ typedef struct svn_cl__opt_state_t
   const char *native_eol;        /* override system standard eol marker */
   svn_boolean_t remove;          /* deassociate a changelist */
   apr_array_header_t *changelists; /* changelist filters */
-  const char *changelist;        /* operate on this changelist
-                                    THIS IS TEMPORARY (LAST OF CHANGELISTS) */
   svn_boolean_t keep_changelists;/* don't remove changelists after commit */
   svn_boolean_t keep_local;      /* delete path only from repository */
   svn_boolean_t all_revprops;    /* retrieve all revprops */
   svn_boolean_t no_revprops;     /* retrieve no revprops */
-  apr_hash_t *revprop_table;     /* table of revision properties to get/set */
+  apr_hash_t *revprop_table;     /* table of revision properties to get/set
+                                    (not converted to UTF-8) */
   svn_boolean_t parents;         /* create intermediate directories */
   svn_boolean_t use_merge_history; /* use/display extra merge information */
   svn_cl__accept_t accept_which;   /* how to handle conflicts */

Modified: subversion/trunk/subversion/svn/svn.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svn/svn.c?rev=1476461&r1=1476460&r2=1476461&view=diff
==============================================================================
--- subversion/trunk/subversion/svn/svn.c (original)
+++ subversion/trunk/subversion/svn/svn.c Sat Apr 27 01:19:38 2013
@@ -1722,7 +1722,7 @@ sub_main(int argc, const char *argv[], a
   apr_array_header_t *received_opts;
   int i;
   const svn_opt_subcommand_desc2_t *subcommand = NULL;
-  const char *dash_m_arg = NULL, *dash_F_arg = NULL;
+  const char *dash_F_arg = NULL;
   svn_cl__cmd_baton_t command_baton;
   svn_auth_baton_t *ab;
   svn_config_t *cfg_config;
@@ -1798,7 +1798,8 @@ sub_main(int argc, const char *argv[], a
       switch (opt_id) {
       case 'l':
         {
-          err = svn_cstring_atoi(&opt_state.limit, opt_arg);
+          SVN_INT_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
+          err = svn_cstring_atoi(&opt_state.limit, utf8_opt_arg);
           if (err)
             {
               err = svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, err,
@@ -1814,16 +1815,17 @@ sub_main(int argc, const char *argv[], a
         }
         break;
       case 'm':
-        /* Note that there's no way here to detect if the log message
-           contains a zero byte -- if it does, then opt_arg will just
-           be shorter than the user intended.  Oh well. */
+        /* We store the raw message here.  We will convert it to UTF-8
+         * later, according to the value of the '--encoding' option. */
         opt_state.message = apr_pstrdup(pool, opt_arg);
-        dash_m_arg = opt_arg;
         break;
       case 'c':
         {
-          apr_array_header_t *change_revs =
-            svn_cstring_split(opt_arg, ", \n\r\t\v", TRUE, pool);
+          apr_array_header_t *change_revs;
+
+          SVN_INT_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
+          change_revs = svn_cstring_split(utf8_opt_arg, ", \n\r\t\v", TRUE,
+                                          pool);
 
           if (opt_state.old_target)
             {
@@ -1918,10 +1920,10 @@ sub_main(int argc, const char *argv[], a
         break;
       case 'r':
         opt_state.used_revision_arg = TRUE;
+        SVN_INT_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
         if (svn_opt_parse_revision_to_range(opt_state.revision_ranges,
-                                            opt_arg, pool) != 0)
+                                            utf8_opt_arg, pool) != 0)
           {
-            SVN_INT_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
             err = svn_error_createf
                 (SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
                  _("Syntax error in revision argument '%s'"),
@@ -1946,20 +1948,19 @@ sub_main(int argc, const char *argv[], a
         opt_state.incremental = TRUE;
         break;
       case 'F':
+        /* We read the raw file content here.  We will convert it to UTF-8
+         * later (if it's a log/lock message or an svn:* prop value),
+         * according to the value of the '--encoding' option. */
         SVN_INT_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
         SVN_INT_ERR(svn_stringbuf_from_file2(&(opt_state.filedata),
                                              utf8_opt_arg, pool));
         reading_file_from_stdin = (strcmp(utf8_opt_arg, "-") == 0);
-        dash_F_arg = opt_arg;
+        dash_F_arg = utf8_opt_arg;
         break;
       case opt_targets:
         {
           svn_stringbuf_t *buffer, *buffer_utf8;
 
-          /* We need to convert to UTF-8 now, even before we divide
-             the targets into an array, because otherwise we wouldn't
-             know what delimiter to use for svn_cstring_split().  */
-
           SVN_INT_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
           SVN_INT_ERR(svn_stringbuf_from_file2(&buffer, utf8_opt_arg, pool));
           SVN_INT_ERR(svn_utf_stringbuf_to_utf8(&buffer_utf8, buffer, pool));
@@ -2109,17 +2110,16 @@ sub_main(int argc, const char *argv[], a
                _("Can't specify -c with --old"));
             return EXIT_ERROR(err);
           }
-        opt_state.old_target = apr_pstrdup(pool, opt_arg);
+        SVN_INT_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
+        opt_state.old_target = apr_pstrdup(pool, utf8_opt_arg);
         break;
       case opt_new_cmd:
-        opt_state.new_target = apr_pstrdup(pool, opt_arg);
+        SVN_INT_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
+        opt_state.new_target = apr_pstrdup(pool, utf8_opt_arg);
         break;
       case opt_config_dir:
-        {
-          const char *path_utf8;
-          SVN_INT_ERR(svn_utf_cstring_to_utf8(&path_utf8, opt_arg, pool));
-          opt_state.config_dir = svn_dirent_internal_style(path_utf8, pool);
-        }
+        SVN_INT_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
+        opt_state.config_dir = svn_dirent_internal_style(utf8_opt_arg, pool);
         break;
       case opt_config_options:
         if (!opt_state.config_options)
@@ -2127,9 +2127,9 @@ sub_main(int argc, const char *argv[], a
                    apr_array_make(pool, 1,
                                   sizeof(svn_cmdline__config_argument_t*));
 
-        SVN_INT_ERR(svn_utf_cstring_to_utf8(&opt_arg, opt_arg, pool));
+        SVN_INT_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
         SVN_INT_ERR(svn_cmdline__parse_config_option(opt_state.config_options,
-                                                     opt_arg, pool));
+                                                     utf8_opt_arg, pool));
         break;
       case opt_autoprops:
         opt_state.autoprops = TRUE;
@@ -2138,12 +2138,12 @@ sub_main(int argc, const char *argv[], a
         opt_state.no_autoprops = TRUE;
         break;
       case opt_native_eol:
-        if ( !strcmp("LF", opt_arg) || !strcmp("CR", opt_arg) ||
-             !strcmp("CRLF", opt_arg))
-          opt_state.native_eol = apr_pstrdup(pool, opt_arg);
+        SVN_INT_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
+        if ( !strcmp("LF", utf8_opt_arg) || !strcmp("CR", utf8_opt_arg) ||
+             !strcmp("CRLF", utf8_opt_arg))
+          opt_state.native_eol = utf8_opt_arg;
         else
           {
-            SVN_INT_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
             err = svn_error_createf
                 (SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
                  _("Syntax error in native-eol argument '%s'"),
@@ -2162,14 +2162,13 @@ sub_main(int argc, const char *argv[], a
         break;
       case opt_changelist:
         SVN_INT_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
-        opt_state.changelist = utf8_opt_arg;
-        if (opt_state.changelist[0] == '\0')
+        if (utf8_opt_arg[0] == '\0')
           {
             err = svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
                                    _("Changelist names must not be empty"));
             return EXIT_ERROR(err);
           }
-        svn_hash_sets(changelists, opt_state.changelist, (void *)1);
+        svn_hash_sets(changelists, utf8_opt_arg, (void *)1);
         break;
       case opt_keep_changelists:
         opt_state.keep_changelists = TRUE;
@@ -2196,31 +2195,35 @@ sub_main(int argc, const char *argv[], a
         opt_state.use_merge_history = TRUE;
         break;
       case opt_accept:
-        opt_state.accept_which = svn_cl__accept_from_word(opt_arg);
+        SVN_INT_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
+        opt_state.accept_which = svn_cl__accept_from_word(utf8_opt_arg);
         if (opt_state.accept_which == svn_cl__accept_invalid)
           return EXIT_ERROR
             (svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
                                _("'%s' is not a valid --accept value"),
-                               opt_arg));
+                               utf8_opt_arg));
         break;
       case opt_show_revs:
-        opt_state.show_revs = svn_cl__show_revs_from_word(opt_arg);
+        SVN_INT_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
+        opt_state.show_revs = svn_cl__show_revs_from_word(utf8_opt_arg);
         if (opt_state.show_revs == svn_cl__show_revs_invalid)
           return EXIT_ERROR
             (svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
                                _("'%s' is not a valid --show-revs value"),
-                               opt_arg));
+                               utf8_opt_arg));
         break;
       case opt_reintegrate:
         opt_state.reintegrate = TRUE;
         break;
       case opt_strip:
         {
-          err = svn_cstring_atoi(&opt_state.strip, opt_arg);
+          SVN_INT_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
+          err = svn_cstring_atoi(&opt_state.strip, utf8_opt_arg);
           if (err)
             {
               err = svn_error_createf(SVN_ERR_CL_ARG_PARSING_ERROR, err,
-                                      _("Invalid strip count '%s'"), opt_arg);
+                                      _("Invalid strip count '%s'"),
+                                      utf8_opt_arg);
               return EXIT_ERROR(err);
             }
           if (opt_state.strip < 0)
@@ -2265,10 +2268,12 @@ sub_main(int argc, const char *argv[], a
         opt_state.diff.properties_only = TRUE;
         break;
       case opt_search:
-        add_search_pattern_group(&opt_state, opt_arg, pool);
+        SVN_INT_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
+        add_search_pattern_group(&opt_state, utf8_opt_arg, pool);
         break;
       case opt_search_and:
-        add_search_pattern_to_latest_group(&opt_state, opt_arg, pool);
+        SVN_INT_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
+        add_search_pattern_to_latest_group(&opt_state, utf8_opt_arg, pool);
       default:
         /* Hmmm. Perhaps this would be a good place to squirrel away
            opts that commands like svn diff might need. Hmmm indeed. */
@@ -2682,10 +2687,10 @@ sub_main(int argc, const char *argv[], a
 
       /* If the -m argument is a file at all, that's probably not what
          the user intended. */
-      if (dash_m_arg)
+      if (opt_state.message)
         {
           apr_finfo_t finfo;
-          if (apr_stat(&finfo, dash_m_arg,
+          if (apr_stat(&finfo, opt_state.message /* not converted to UTF-8 */,
                        APR_FINFO_MIN, pool) == APR_SUCCESS)
             {
               if (subcommand->cmd_func != svn_cl__lock)



Mime
View raw message