{"thread":{"id":"32658","subject":"[PATCH] git-svn: do not escape certain characters in paths","startedAt":"2013-01-17T22:07:31Z","lastAt":"2013-01-19T11:34:21Z","messageCount":2,"participants":["Peter Wu","Eric Wong"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"207173","messageId":"1472347.NT5gjdj3yd@al","threadId":"32658","inReplyTo":null,"subject":"[PATCH] git-svn: do not escape certain characters in paths","fromName":"Peter Wu","fromEmail":"lekensteyn@gmail.com","sentAt":"2013-01-17T22:07:31Z","receivedAt":"2013-01-17T22:07:31Z","isPatch":true,"sender":{"key":"lekensteyn@gmail.com","avatar":"https://avatars.githubusercontent.com/u/164530?v=4"},"body":"Subversion 1.7 and newer implement HTTPv2, an extension that should make HTTP\nmore efficient. Servers with support for this protocol will make the subversion\nclient library take an alternative code path that checks (with assertions)\nwhether the URL is \"canonical\" or not.\n\nThis patch fixes an issue I encountered while trying to `git svn dcommit` a\nrename action for a file containing a single quote character (\"User's Manual\"\nto \"UserMan.tex\"). It does not happen for older subversion 1.6 servers nor\nnon-HTTP(S) protocols such as the native svn protocol, only on an Apache server\nshipping SVN 1.7. Trying to `git svn dcommit` under the aforementioned\nconditions yields the following error which aborts the commit process:\n\n    Committing to http://example.com/svn ...\n    perl: subversion/libsvn_subr/dirent_uri.c:1520: uri_skip_ancestor:\nAssertion `svn_uri_is_canonical(child_uri, ((void *)0))' failed.\n    error: git-svn died of signal 6\n\nAn analysis of the subversion source for the cause:\n\n- The assertion originates from uri_skip_ancestor which calls\n  svn_uri_is_canonical, which fails when the URL contains percent-encoded values\n  that do not necessarily have to be encoded (not \"canonical\" enough). This is\n  done by a table lookup in libsvn_subr/path.c. Putting some debugging prints\n  revealed that the character ' is indeed encoded to %27 which is not\n  considered canonical.\n- url_skip_ancestor is called by svn_ra_neon__get_baseline_info with the root\n  repository URL and path as parameters;\n- which is called by copy_resource (libsvn_ra_neon/commit.c) for a copy action\n  (or in my case, renaming which is actually copy + delete old);\n- which is called by commit_add_dir;\n- which is assigned as a structure method \"add_file\" in\n  svn_ra_neon__get_commit_editor.\n\nIn the whole path, the path argument is not modified.\n\nThrough some more uninteresting wrapper functions, the Perl bindings gives you\naccess to the add_file method which will pass the path argument without\nmodifications to svn.\n\ngit-svn calls the \"R\"(ename) subroutine in Git::SVN::Editor which contains:\n326         my $fbat = $self->add_file($self->repo_path($m->{file_b}), $pbat,\n327                                 $self->url_path($m->{file_a}), $self->{r});\n\"repo_path\" basically returns the path as-is, unless the \"svn.pathnameencoding\"\nconfiguration property is set. \"url_path\" tries to escape some special\ncharacters, but does not take all special characters into account, thereby\ncausing the path to contain some escaped characters which do not have to be\nescaped.\n\nThe list of characters not to be escaped are taken from the\nsubversion/libsvn_subr/path.c file to fully account for all characters. Tested\nwith a filename containing all characters in the range 0x20 to 0x78 (inclusive).\n\nSigned-off-by: Peter Wu <lekensteyn@gmail.com>\n---\n perl/Git/SVN/Editor.pm | 3 ++-\n 1 file changed, 2 insertions(+), 1 deletion(-)\n\ndiff --git a/perl/Git/SVN/Editor.pm b/perl/Git/SVN/Editor.pm\nindex 3bbc20a..30f92cb 100644\n--- a/perl/Git/SVN/Editor.pm\n+++ b/perl/Git/SVN/Editor.pm\n@@ -145,7 +145,8 @@ sub repo_path {\n sub url_path {\n \tmy ($self, $path) = @_;\n \tif ($self->{url} =~ m#^https?://#) {\n-\t\t$path =~ s!([^~a-zA-Z0-9_./-])!uc sprintf(\"%%%02x\",ord($1))!eg;\n+\t\t# characters are taken from subversion/libsvn_subr/path.c\n+\t\t$path =~ s#([^~a-zA-Z0-9_./!$&'()*+,-])#uc sprintf(\"%%%02x\",ord($1))#eg;\n \t}\n \t$self->{url} . '/' . $self->repo_path($path);\n }\n-- \n1.8.1.1\n"},{"id":"207258","messageId":"20130119113421.GA9846@dcvr.yhbt.net","threadId":"32658","inReplyTo":"1472347.NT5gjdj3yd@al","subject":"Re: [PATCH] git-svn: do not escape certain characters in paths","fromName":"Eric Wong","fromEmail":"normalperson@yhbt.net","sentAt":"2013-01-19T11:34:21Z","receivedAt":"2013-01-19T11:34:21Z","isPatch":true,"sender":{"key":"e@80x24.org","avatar":null},"body":"Peter Wu <lekensteyn@gmail.com> wrote:\n> Signed-off-by: Peter Wu <lekensteyn@gmail.com>\n\nThanks, Signed-off-by: Eric Wong <normalperson@yhbt.net>\n\nWill push.\n"}]}