From 0f57b8d2dec6c2c458bd7c35c05fe7433928dec9 Mon Sep 17 00:00:00 2001 From: epriestley Date: Fri, 15 Feb 2013 14:53:25 -0800 Subject: [PATCH] Fix various SVN escaping issues in arc patch Summary: Followup to D4703. When we give paths to `svn`, we need to escape them if they contain an `@`. Test Plan: Created a patch full of modifications to files with `@` in their names, and applied it: $ arc patch --diff 192 A A@2xcopy2 A A@2xcopy D A@2x OKAY Successfully applied patch to the working copy. Reviewers: chad, mbishopim3 Reviewed By: chad CC: aran Differential Revision: https://secure.phabricator.com/D4977 --- src/repository/api/ArcanistSubversionAPI.php | 17 ++++++++++++----- src/workflow/ArcanistPatchWorkflow.php | 12 ++++++------ 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/src/repository/api/ArcanistSubversionAPI.php b/src/repository/api/ArcanistSubversionAPI.php index f247b238..2f757639 100644 --- a/src/repository/api/ArcanistSubversionAPI.php +++ b/src/repository/api/ArcanistSubversionAPI.php @@ -644,18 +644,25 @@ EODIFF; } public static function escapeFileNamesForSVN(array $files) { + foreach ($files as $k => $file) { + $files[$k] = self::escapeFileNameForSVN($file); + } + return $files; + } + + public static function escapeFileNameForSVN($file) { // SVN interprets "x@1" as meaning "file x at revision 1", which is not // intended for files named "sprite@2x.png" or similar. For files with an // "@" in their names, escape them by adding "@" at the end, which SVN // interprets as "at the working copy revision". There is a special case // where ".@" means "fail with an error" instead of ". at the working copy // revision", so avoid escaping "." into ".@". - foreach ($files as $k => $file) { - if (strpos($file, '@') !== false) { - $files[$k] = $file.'@'; - } + + if (strpos($file, '@') !== false) { + $file = $file.'@'; } - return $files; + + return $file; } } diff --git a/src/workflow/ArcanistPatchWorkflow.php b/src/workflow/ArcanistPatchWorkflow.php index e9fa45a9..a8eab2b6 100644 --- a/src/workflow/ArcanistPatchWorkflow.php +++ b/src/workflow/ArcanistPatchWorkflow.php @@ -578,8 +578,8 @@ EOTEXT csprintf( '(cd %s; svn cp %s %s)', $repository_api->getPath(), - $src, - $dst)); + ArcanistSubversionAPI::escapeFileNameForSVN($src), + ArcanistSubversionAPI::escapeFileNameForSVN($dst))); } foreach ($deletes as $delete) { @@ -587,7 +587,7 @@ EOTEXT csprintf( '(cd %s; svn rm %s)', $repository_api->getPath(), - $delete)); + ArcanistSubversionAPI::escapeFileNameForSVN($delete))); } foreach ($symlinks as $symlink) { @@ -636,7 +636,7 @@ EOTEXT csprintf( '(cd %s; svn add %s)', $repository_api->getPath(), - $add)); + ArcanistSubversionAPI::escapeFileNameForSVN($add))); } foreach ($propset as $path => $changes) { @@ -652,7 +652,7 @@ EOTEXT '(cd %s; svn propdel %s %s)', $repository_api->getPath(), $prop, - $path)); + ArcanistSubversionAPI::escapeFileNameForSVN($path))); } else { passthru( csprintf( @@ -660,7 +660,7 @@ EOTEXT $repository_api->getPath(), $prop, $value, - $path)); + ArcanistSubversionAPI::escapeFileNameForSVN($path))); } } }