Uploaded image for project: 'Subversion'
  1. Subversion
  2. SVN-3278

Merges involving filenames with spaces are problematic

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Blocker
    • Resolution: Fixed
    • 1.5.x
    • 1.7.0
    • libsvn_ra_neon
    • None

    Description

      I am having issues with merging trees which have spaces in the directory names.
       This issue is a total blocker for us.
      
      I get an error such as:
      
      svn: URL 'http://server/svn/repos/trunk/module with spaces' is malformed or the
      scheme or host or path is missing
      
      
      The root of the problem traces back to the "libsvn_ra_neon/session.c" file.
      In particular, the parse_url method is passing in the repository url directly to
      the "ne_uri_parse" function.  
      
      However, if the URL has spaces in the path, then the "ne_uri_parse" function
      exits, and the "path" field in the  "ne_uri" struct is left null.  This causes
      subversion to issue the above error and fail.
      
      The solution is to escape the path component of the URL prior to calling into
      the "ne_uri_parse" function.  
      
        http://server/svn/repos/trunk/module with spaces
      
      would become
      
        http://server/svn/repos/trunk/module%20with%20spaces
      
      I have made this fix locally, and it seems to work perfectly.  To apply this fix:
      
      neon/src/ne_uri.h
      ---------------------
      // Find the position in the uri where the path component starts
      int ne_path_find(const char *uri);
      
      
      neon/src/ne_uri.c
      ---------------------
      int ne_path_find(const char *uri) {
          const char *p, *s;
      
          p = s = uri;
      
          /* => s = p = URI-reference */
      
          if (uri_lookup(*p) & URI_ALPHA) {
              while (uri_lookup(*p) & URI_SCHEME)
                  p++;
              
              if (*p == ':') {
                  s = p + 1;
              }
          }
      
          /* => s = heir-part, or s = relative-part */
      
          if (s[0] == '/' && s[1] == '/') {
              const char *pa;
      
              /* => s = "//" authority path-abempty (from expansion of
               * either heir-part of relative-part)  */
              
              /* authority = [ userinfo "@" ] host [ ":" port ] */
      
              s = pa = s + 2; /* => s = authority */
      
              while (*pa != '/' && *pa != '\0')
                  pa++;
              /* => pa = path-abempty */
              
              p = s;
              while (p < pa && uri_lookup(*p) & URI_USERINFO)
                  p++;
      
              if (*p == '@') {
                  s = p + 1;
              }
              /* => s = host */
      
              if (s[0] == '[') {
                  p = s + 1;
      
                  while (*p != ']' && p < pa)
                      p++;
      
                  if (p == pa || (p + 1 != pa && p[1] != ':')) {
                      /* Ill-formed IP-literal. */
                      return -1;
                  }
      
                  p++; /* => p = colon */
              } else {
                  /* Find the colon. */
                  p = pa;
                  while (*p != ':' && p > s)
                      p--;
              }
      
              if (p == s) {
                  p = pa;
                  /* No colon; => p = path-abempty */
              } else if (p + 1 != pa) {
                  /* => p = colon */
              }
              
              s = pa;        
      
              if (*s == '\0') {
                  s = "/"; /* FIXME: scheme-specific. */
              }
          }
      
          /* => s = path-abempty / path-absolute / path-rootless
           *      / path-empty / path-noscheme */
      
          p = s;
      
          return strlen(uri) - strlen(p);
      }
      
      
      libsvn_ra_neon/session.c
      ---------------------------
      static svn_error_t *
      parse_url(ne_uri *uri, const char *url)
      {
        char * uri_esc;
      
        int ppos = ne_path_find(url);
        if (ppos != -1) {
          char * pe = ne_path_escape(url + ppos);
          uri_esc = ne_malloc(ppos + strlen(pe) + 1);
          strncpy(uri_esc, url, ppos);
          strcpy(uri_esc + ppos, pe);
          ne_free(pe);
        }
        else {
          uri_esc = ne_malloc(strlen(url) + 1);
          strcpy(uri_esc, url);
        }
      
        if (ne_uri_parse(uri_esc, uri)
            || uri->host == NULL || uri->path == NULL || uri->scheme == NULL)
          {
            ne_uri_free(uri);
            return svn_error_createf(SVN_ERR_RA_ILLEGAL_URL, NULL,
                                     _("URL '%s' is malformed or the "
                                       "scheme or host or path is missing"), url);
          }
        if (uri->port == 0)
          uri->port = ne_uri_defaultport(uri->scheme);
      
        ne_free(uri_esc);
      
        return SVN_NO_ERROR;
      }
      

      http://subversion.tigris.org/servlets/ReadMsg?listName=dev&msgNo=142489

      Original issue reported by mattinger

      Attachments

        Activity

          People

            Unassigned Unassigned
            subversion-importer Subversion Importer
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: