[svk-commit] r2731 - in trunk: lib/SVK lib/SVK/Mirror/Backend

nobody at bestpractical.com nobody at bestpractical.com
Thu Apr 17 04:18:29 EDT 2008


Author: clsung
Date: Thu Apr 17 04:18:29 2008
New Revision: 2731

Added:
   trunk/t/uri-escape-dav.t
   trunk/t/uri-escape.t
Modified:
   trunk/lib/SVK/Mirror.pm
   trunk/lib/SVK/Mirror/Backend/SVNRa.pm
   trunk/lib/SVK/Util.pm

Log:
- add uri_escape uri_unescape functions to Util.pm
- escape uri while dealing with SVN::Mirror and SVN::Ra
- unescape uri if user input escaped url
- two tests to address them

Modified: trunk/lib/SVK/Mirror.pm
==============================================================================
--- trunk/lib/SVK/Mirror.pm	(original)
+++ trunk/lib/SVK/Mirror.pm	Thu Apr 17 04:18:29 2008
@@ -57,6 +57,7 @@
 
 use Sys::Hostname;
 use SVK::I18N;
+use SVK::Util qw(uri_escape uri_unescape);
 use Scalar::Util 'weaken';
 
 use base 'Class::Accessor::Fast';
@@ -118,6 +119,7 @@
     my $self = $class->SUPER::new($args);
 
     $self->{url} =~ s{/+$}{}g;
+    $self->{url} = uri_unescape($self->{url});
 
     $self->pool( SVN::Pool->new(undef) )
         unless $self->pool;
@@ -426,7 +428,11 @@
     my $target = $self->get_svkpath;
 
     my $lock_message = $self->_lock_message;
+    my $escaped_url = uri_escape($self->url);
+	    
+    # XXX if SVN::Mirror do uri_escape in future, then we can remove 'source => $escaped_url' line
     my $svm = SVN::Mirror->new(
+        source => $escaped_url,
         target_path    => $self->path,
         repos          => $self->depot->repos,
         config         => SVK::Config->svnconfig,

Modified: trunk/lib/SVK/Mirror/Backend/SVNRa.pm
==============================================================================
--- trunk/lib/SVK/Mirror/Backend/SVNRa.pm	(original)
+++ trunk/lib/SVK/Mirror/Backend/SVNRa.pm	Thu Apr 17 04:18:29 2008
@@ -58,7 +58,7 @@
 use SVK::Editor;
 use SVK::Mirror::Backend::SVNRaPipe;
 use SVK::Editor::MapRev;
-use SVK::Util 'IS_WIN32';
+use SVK::Util qw(IS_WIN32 uri_escape);
 use SVK::Logger;
 use SVK::Editor::FilterProp;
 use SVK::Editor::Composite;
@@ -323,7 +323,7 @@
 
     if ( $self->_cached_ra ) {
         my $ra = delete $self->{_cached_ra};
-        my $url = $args{url} || $self->mirror->url;
+        my $url = uri_escape($args{url} || $self->mirror->url);
         return $ra if $ra->{url} eq $url;
         if ( _p_svn_ra_session_t->can('reparent') ) {
             $ra->reparent($url);
@@ -333,7 +333,7 @@
     }
     $self->_initialize_svn;
     return SVN::Ra->new(
-        url    => $self->mirror->url,
+        url    => uri_escape($self->mirror->url),
         auth   => $self->_auth_baton,
         config => $self->_config,
         %args

Modified: trunk/lib/SVK/Util.pm
==============================================================================
--- trunk/lib/SVK/Util.pm	(original)
+++ trunk/lib/SVK/Util.pm	Thu Apr 17 04:18:29 2008
@@ -70,6 +70,8 @@
 
     is_symlink is_executable is_uri can_run is_path_inside
 
+    uri_escape uri_unescape
+
     str2time time2str reformat_svn_date
 
     find_dotsvk
@@ -1014,6 +1016,30 @@
     return substr ($path, 0, length ($parent)+1) eq "$parent/";
 }
 
+=head3 uri_escape($uri)
+
+Returns escaped URI.
+
+=cut
+
+sub uri_escape {
+    my ($uri) = @_;
+    $uri =~ s/([^0-9A-Za-z%\-\/:_.!~*'()])/sprintf("%%%02X", ord($1))/eg;
+    return $uri;
+}
+
+=head3 uri_unescape($uri)
+
+Unescape escaped URI and return it.
+
+=cut
+
+sub uri_unescape {
+    my ($uri) = @_;
+    $uri =~ s/%([0-9A-Fa-f]{2})/chr(hex($1))/eg;
+    return $uri;
+}
+
 1;
 
 __END__

Added: trunk/t/uri-escape-dav.t
==============================================================================
--- (empty file)
+++ trunk/t/uri-escape-dav.t	Thu Apr 17 04:18:29 2008
@@ -0,0 +1,126 @@
+#!/usr/bin/perl -w
+use strict;
+# XXX: apache::test seems to alter inc to use blib
+require SVK::Command::Merge;
+use POSIX qw(setlocale LC_CTYPE);
+
+
+# XXX: apache::TestConfig assumes lib.pm is compiled.
+require lib;
+
+use SVK::Util qw(can_run uri_escape $EOL);
+
+BEGIN {
+use SVK::Test;
+    plan (skip_all => "Test does not run under root") if $> == 0;
+    eval { require Apache2 };
+    eval { require Apache::Test;
+	   $Apache::Test::VERSION >= 1.18 }
+	or plan (skip_all => "Apache::Test 1.18 required for testing dav");
+}
+setlocale (LC_CTYPE, $ENV{LC_CTYPE} = 'en_US.UTF-8')
+    or plan skip_all => 'cannot set locale to en_US.UTF-8';
+
+use Apache::TestConfig;
+use File::Spec::Functions qw(rel2abs catdir catfile);
+
+our $output;
+
+my ($xd, $svk) = build_test('test');
+
+my $depotpath = '/test/';
+my $pool = SVN::Pool->new_default;
+my ($depot, $path) = $xd->find_depotpath($depotpath);
+{
+    local $/ = $EOL;
+    my $edit = get_editor ($depot->repospath, $path, $depot->repos);
+    $edit->open_root ();
+
+    $edit->add_directory ('/B and K');
+    $edit->add_directory ('/B and K/A');
+    $edit->add_directory ('/B and K/A/N P1');
+    $edit->add_directory ('/B and K/A/N P1/trunk');
+    $edit->add_directory ('/B and K/A/N P1/trunk/doc');
+    $edit->modify_file (
+	$edit->add_file ('/B and K/A/N P1/trunk/doc/ReadMe.txt'),
+			"first line in pe$/2nd line in pe$/");
+    $edit->add_directory ('/B and K/A/N P1/trunk/src');
+    $edit->add_directory ('/B and K/A/N P1/trunk/data');
+    $edit->add_directory ('/B and K/A/N P1/branches');
+    $edit->add_directory ('/B and K/A/N P1/tags');
+    $edit->close_edit ();
+}
+my ($srepospath, $spath, $srepos) = $xd->find_repos ('/test/B and K', 1);
+my (undef, undef, $repos) = $xd->find_repos ('//', 1);
+
+my $apache_root = rel2abs (catdir ('t', 'apache_svn'));
+my $apxs = $ENV{APXS} || can_run('apxs2') || can_run ('apxs');
+plan skip_all => "Can't find apxs utility. Use APXS env to specify path" unless $apxs;
+
+my $cfg = Apache::TestConfig->new
+    ( top_dir => $apache_root,
+      t_dir => $apache_root,
+      apxs => $apxs,
+ )->httpd_config;
+
+plan skip_all => "apache 2.2 changed auth directives."
+    if $cfg->server->{version} =~ m|Apache/2\.2|;
+
+unless ($cfg->can('find_and_load_module') and
+	$cfg->find_and_load_module ('mod_dav.so') and
+	$cfg->find_and_load_module ('mod_dav_svn.so') and
+        $cfg->find_and_load_module ('mod_authz_svn.so')) {
+    plan skip_all => "Can't find mod_dav_svn and mod_authz_svn";
+}
+
+plan tests => 6;
+
+$cfg->postamble (Location => "/svn",
+		 qq{DAV svn\n    SVNPath $depot->{repospath}\n});
+$cfg->generate_httpd_conf;
+my $server = $cfg->server;
+
+$server->start;
+ok ($server->ping, 'server is alive');
+
+my $uri = 'http://'.$server->{name}.'/svn';
+my $uri_trunk = $uri.'/B and K/A/N P1/trunk';
+my $uri_trunk_escape = uri_escape($uri_trunk);
+
+$svk->mirror('//mirror/BK', $uri_trunk);
+
+is_output ($svk, 'mirror', ['--list'], [
+    "Path          Source",
+    "============================================================",
+    "//mirror/BK   $uri/B and K/A/N P1/trunk"]);
+
+is_output ($svk, 'sync', ['//mirror/BK'], [
+    "Syncing $uri/B and K/A/N P1/trunk",
+    "Retrieving log information from 1 to 1",
+    "Committed revision 2 from revision 1."]);
+
+# detach and try with snapshot sync
+$svk->mirror ('-d','//mirror/BK');
+
+$svk->mirror('//mirror/BK2', $uri_trunk);
+
+is_output ($svk, 'sync', [-s => 'HEAD', '//mirror/BK2'],
+          [(map { qr'.*'} (1..8)),
+	   'Syncing '.$uri_trunk_escape,
+	   'Retrieving log information from 1 to 1',
+	   'Committed revision 5 from revision 1.',
+	   'Syncing '.$uri_trunk]);
+
+$svk->mirror ('-d','//mirror/BK2');
+
+$svk->mirror('//mirror/BK3', $uri_trunk_escape);
+
+is_output ($svk, 'sync', ['//mirror/BK3'], [
+    "Syncing $uri_trunk",
+    "Retrieving log information from 1 to 1",
+    "Committed revision 8 from revision 1."]);
+
+is_output ($svk, 'mirror', ['--list'], [
+    "Path           Source",
+    "=============================================================",
+    "//mirror/BK3   $uri/B and K/A/N P1/trunk"]);

Added: trunk/t/uri-escape.t
==============================================================================
--- (empty file)
+++ trunk/t/uri-escape.t	Thu Apr 17 04:18:29 2008
@@ -0,0 +1,58 @@
+#!/usr/bin/perl -w
+use strict;
+use SVK::Test;
+use SVK::Util qw($EOL uri_escape);
+plan tests => 3;
+our $output;
+
+my ($xd, $svk) = build_test('test');
+
+my $depotpath = '/test/';
+my $pool = SVN::Pool->new_default;
+my ($depot, $path) = $xd->find_depotpath($depotpath);
+{
+    local $/ = $EOL;
+    my $edit = get_editor ($depot->repospath, $path, $depot->repos);
+    $edit->open_root ();
+
+    $edit->add_directory ('/B and K');
+    $edit->add_directory ('/B and K/A');
+    $edit->add_directory ('/B and K/A/N P1');
+    $edit->add_directory ('/B and K/A/N P1/trunk');
+    $edit->add_directory ('/B and K/A/N P1/trunk/doc');
+    $edit->modify_file (
+	$edit->add_file ('/B and K/A/N P1/trunk/doc/ReadMe.txt'),
+			"first line in pe$/2nd line in pe$/");
+    $edit->add_directory ('/B and K/A/N P1/trunk/src');
+    $edit->add_directory ('/B and K/A/N P1/trunk/data');
+    $edit->add_directory ('/B and K/A/N P1/branches');
+    $edit->add_directory ('/B and K/A/N P1/tags');
+    $edit->close_edit ();
+}
+my $uri = uri($depot->repospath);
+my $uri_trunk = $uri.'/B and K/A/N P1/trunk';
+my $uri_trunk_escape = uri_escape($uri_trunk);
+
+$svk->mirror('//mirror/BK', $uri_trunk);
+
+is_output ($svk, 'mirror', ['--list'], [
+    "Path          Source",
+    "==========================================================",
+    "//mirror/BK   $uri/B and K/A/N P1/trunk"]);
+
+is_output ($svk, 'sync', ['//mirror/BK'], [
+    "Syncing $uri/B and K/A/N P1/trunk",
+    "Retrieving log information from 1 to 1",
+    "Committed revision 2 from revision 1."]);
+
+# detach and try with snapshot sync
+$svk->mirror ('-d','//mirror/BK');
+
+$svk->mirror('//mirror/BK2', $uri_trunk);
+
+is_output ($svk, 'sync', [-s => 'HEAD', '//mirror/BK2'],
+          [(map { qr'.*'} (1..8)),
+	   'Syncing '.$uri_trunk_escape,
+	   'Retrieving log information from 1 to 1',
+	   'Committed revision 5 from revision 1.',
+	   'Syncing '.$uri_trunk]);


More information about the svk-commit mailing list