about summary refs log tree commit homepage
path: root/lib/PublicInbox
diff options
context:
space:
mode:
authorEric Wong <e@80x24.org>2021-05-09 11:16:13 +0000
committerEric Wong <e@80x24.org>2021-05-09 18:23:17 +0000
commit54bc9f163df414237eeb153b4c3c70ca0e9a61f4 (patch)
tree2ed8c1e42d8f8224c5775c0cdb53a6755b46a0b3 /lib/PublicInbox
parent36fa9327fd83085d9384e3d1941d9ca678308149 (diff)
downloadpublic-inbox-54bc9f163df414237eeb153b4c3c70ca0e9a61f4.tar.gz
git always quotes with leading zeros to ensure the octal
representation is 3 characters long.  We enforce that to match
low ASCII characters (e.g. [x01-\x06]) that don't need the
range provided by 3 characters.

git_unquote now does a single pass so it won't get fooled by
decoded backslashes into parsing a digit as an octal character.
git_unquote is also capped to "\377" so we don't overflow a
byte.
Diffstat (limited to 'lib/PublicInbox')
-rw-r--r--lib/PublicInbox/Git.pm5
1 files changed, 2 insertions, 3 deletions
diff --git a/lib/PublicInbox/Git.pm b/lib/PublicInbox/Git.pm
index 96ac17a3..e557f6d6 100644
--- a/lib/PublicInbox/Git.pm
+++ b/lib/PublicInbox/Git.pm
@@ -50,14 +50,13 @@ my %ESC_GIT = map { $GIT_ESC{$_} => $_ } keys %GIT_ESC;
 sub git_unquote ($) {
         return $_[0] unless ($_[0] =~ /\A"(.*)"\z/);
         $_[0] = $1;
-        $_[0] =~ s/\\([\\"abfnrtv])/$GIT_ESC{$1}/g;
-        $_[0] =~ s/\\([0-7]{1,3})/chr(oct($1))/ge;
+        $_[0] =~ s!\\([\\"abfnrtv]|[0-3][0-7]{2})!$GIT_ESC{$1}//chr(oct($1))!ge;
         $_[0];
 }
 
 sub git_quote ($) {
         if ($_[0] =~ s/([\\"\a\b\f\n\r\t\013]|[^[:print:]])/
-                      '\\'.($ESC_GIT{$1}||sprintf("%0o",ord($1)))/egs) {
+                      '\\'.($ESC_GIT{$1}||sprintf("%03o",ord($1)))/egs) {
                 return qq{"$_[0]"};
         }
         $_[0];