[SCM] WebKit Debian packaging branch, webkit-1.2, updated. upstream/1.1.90-6072-g9a69373

hamaji at chromium.org hamaji at chromium.org
Wed Apr 7 23:33:00 UTC 2010


The following commit has been merged in the webkit-1.2 branch:
commit 0e18e9c0fafc650762d98bbccf139e042cf33c1e
Author: hamaji at chromium.org <hamaji at chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Thu Nov 12 04:19:07 2009 +0000

    2009-11-11  Shinichiro Hamaji  <hamaji at chromium.org>
    
            Reviewed by Darin Adler.
    
            svn-apply can not handle git binary diffs
            https://bugs.webkit.org/show_bug.cgi?id=26830
    
            Support "literal" type git binary diffs.
    
            * Scripts/VCSUtils.pm:
            * Scripts/modules/scm_unittest.py:
            * Scripts/svn-apply:
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@50863 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebKitTools/ChangeLog b/WebKitTools/ChangeLog
index 0bac779..7c3bb22 100644
--- a/WebKitTools/ChangeLog
+++ b/WebKitTools/ChangeLog
@@ -1,3 +1,16 @@
+2009-11-11  Shinichiro Hamaji  <hamaji at chromium.org>
+
+        Reviewed by Darin Adler.
+
+        svn-apply can not handle git binary diffs
+        https://bugs.webkit.org/show_bug.cgi?id=26830
+
+        Support "literal" type git binary diffs.
+
+        * Scripts/VCSUtils.pm:
+        * Scripts/modules/scm_unittest.py:
+        * Scripts/svn-apply:
+
 2009-11-11  Dmitry Titov  <dimich at chromium.org>
 
         Not reviewed, removing duplicate entry for myself in committers.py.
diff --git a/WebKitTools/Scripts/VCSUtils.pm b/WebKitTools/Scripts/VCSUtils.pm
index abf7335..7638102 100644
--- a/WebKitTools/Scripts/VCSUtils.pm
+++ b/WebKitTools/Scripts/VCSUtils.pm
@@ -44,6 +44,7 @@ BEGIN {
         &changeLogEmailAddress
         &changeLogName
         &chdirReturningRelativePath
+        &decodeGitBinaryPatch
         &determineSVNRoot
         &determineVCSRoot
         &fixChangeLogPatch
@@ -345,8 +346,6 @@ sub gitdiff2svndiff($)
     $_ = shift @_;
     if (m#^diff --git a/(.+) b/(.+)#) {
         return "Index: $1";
-    } elsif (m/^new file.*/) {
-        return "";
     } elsif (m#^index [0-9a-f]{7}\.\.[0-9a-f]{7} [0-9]{6}#) {
         return "===================================================================";
     } elsif (m#^--- a/(.+)#) {
@@ -474,4 +473,98 @@ sub changeLogEmailAddress()
     return $emailAddress;
 }
 
+# http://tools.ietf.org/html/rfc1924
+sub decodeBase85($)
+{
+    my ($encoded) = @_;
+    my %table;
+    my @characters = ('0'..'9', 'A'..'Z', 'a'..'z', '!', '#', '$', '%', '&', '(', ')', '*', '+', '-', ';', '<', '=', '>', '?', '@', '^', '_', '`', '{', '|', '}', '~');
+    for (my $i = 0; $i < 85; $i++) {
+        $table{$characters[$i]} = $i;
+    }
+
+    my $decoded = '';
+    my @encodedChars = $encoded =~ /./g;
+
+    for (my $encodedIter = 0; defined($encodedChars[$encodedIter]);) {
+        my $digit = 0;
+        for (my $i = 0; $i < 5; $i++) {
+            $digit *= 85;
+            my $char = $encodedChars[$encodedIter];
+            $digit += $table{$char};
+            $encodedIter++;
+        }
+
+        for (my $i = 0; $i < 4; $i++) {
+            $decoded .= chr(($digit >> (3 - $i) * 8) & 255);
+        }
+    }
+
+    return $decoded;
+}
+
+sub decodeGitBinaryChunk($$)
+{
+    my ($contents, $fullPath) = @_;
+
+    # Load this module lazily in case the user don't have this module
+    # and won't handle git binary patches.
+    require Compress::Zlib;
+
+    my $encoded = "";
+    my $compressedSize = 0;
+    while ($contents =~ /^([A-Za-z])(.*)$/gm) {
+        my $line = $2;
+        next if $line eq "";
+        die "$fullPath: unexpected size of a line: $&" if length($2) % 5 != 0;
+        my $actualSize = length($2) / 5 * 4;
+        my $encodedExpectedSize = ord($1);
+        my $expectedSize = $encodedExpectedSize <= ord("Z") ? $encodedExpectedSize - ord("A") + 1 : $encodedExpectedSize - ord("a") + 27;
+
+        die "$fullPath: unexpected size of a line: $&" if int(($expectedSize + 3) / 4) * 4 != $actualSize;
+        $compressedSize += $expectedSize;
+        $encoded .= $line;
+    }
+
+    my $compressed = decodeBase85($encoded);
+    $compressed = substr($compressed, 0, $compressedSize);
+    return Compress::Zlib::uncompress($compressed);
+}
+
+sub decodeGitBinaryPatch($$)
+{
+    my ($contents, $fullPath) = @_;
+
+    # Git binary patch has two chunks. One is for the normal patching
+    # and another is for the reverse patching.
+    #
+    # Each chunk a line which starts from either "literal" or "delta",
+    # followed by a number which specifies decoded size of the chunk.
+    # The "delta" type chunks aren't supported by this function yet.
+    #
+    # Then, content of the chunk comes. To decode the content, we
+    # need decode it with base85 first, and then zlib.
+    my $gitPatchRegExp = '(literal|delta) ([0-9]+)\n([A-Za-z0-9!#$%&()*+-;<=>?@^_`{|}~\\n]*?)\n\n';
+    if ($contents !~ m"\nGIT binary patch\n$gitPatchRegExp$gitPatchRegExp\Z") {
+        die "$fullPath: unknown git binary patch format"
+    }
+
+    my $binaryChunkType = $1;
+    my $binaryChunkExpectedSize = $2;
+    my $encodedChunk = $3;
+    my $reverseBinaryChunkType = $4;
+    my $reverseBinaryChunkExpectedSize = $5;
+    my $encodedReverseChunk = $6;
+
+    my $binaryChunk = decodeGitBinaryChunk($encodedChunk, $fullPath);
+    my $binaryChunkActualSize = length($binaryChunk);
+    my $reverseBinaryChunk = decodeGitBinaryChunk($encodedReverseChunk, $fullPath);
+    my $reverseBinaryChunkActualSize = length($reverseBinaryChunk);
+
+    die "$fullPath: unexpected size of the first chunk (expected $binaryChunkExpectedSize but was $binaryChunkActualSize" if ($binaryChunkExpectedSize != $binaryChunkActualSize);
+    die "$fullPath: unexpected size of the second chunk (expected $reverseBinaryChunkExpectedSize but was $reverseBinaryChunkActualSize" if ($reverseBinaryChunkExpectedSize != $reverseBinaryChunkActualSize);
+
+    return ($binaryChunkType, $binaryChunk, $reverseBinaryChunkType, $reverseBinaryChunk);
+}
+
 1;
diff --git a/WebKitTools/Scripts/modules/scm_unittest.py b/WebKitTools/Scripts/modules/scm_unittest.py
index a6a3b71..3f86ef5 100644
--- a/WebKitTools/Scripts/modules/scm_unittest.py
+++ b/WebKitTools/Scripts/modules/scm_unittest.py
@@ -29,6 +29,7 @@
 
 import base64
 import os
+import os.path
 import re
 import stat
 import subprocess
@@ -203,6 +204,83 @@ class SCMTest(unittest.TestCase):
         self.assertTrue(re.search('test2', r3_patch))
         self.assertTrue(re.search('test2', self.scm.diff_for_revision(2)))
 
+    def _shared_test_svn_apply_git_patch(self):
+        self._setup_webkittools_scripts_symlink(self.scm)
+        git_binary_addition = """diff --git a/fizzbuzz7.gif b/fizzbuzz7.gif
+new file mode 100644
+index 0000000000000000000000000000000000000000..64a9532e7794fcd791f6f12157406d90
+60151690
+GIT binary patch
+literal 512
+zcmZ?wbhEHbRAx|MU|?iW{Kxc~?KofD;ckY;H+&5HnHl!!GQMD7h+sU{_)e9f^V3c?
+zhJP##HdZC#4K}7F68@!1jfWQg2daCm-gs#3|JREDT>c+pG4L<_2;w##WMO#ysPPap
+zLqpAf1OE938xAsSp4!5f-o><?VKe(#0jEcwfHGF4%M1^kRs14oVBp2ZEL{E1N<-zJ
+zsfLmOtKta;2_;2c#^S1-8cf<nb!QnGl>c!Xe6RXvrEtAWBvSDTgTO1j3vA31Puw!A
+zs(87q)j_mVDTqBo-P+03-P5mHCEnJ+x}YdCuS7#bCCyePUe(ynK+|4b-3qK)T?Z&)
+zYG+`tl4h?GZv_$t82}X4*DTE|$;{DEiPyF@)U-1+FaX++T9H{&%cag`W1|zVP@`%b
+zqiSkp6{BTpWTkCr!=<C6Q=?#~R8^JfrliAF6Q^gV9Iup8RqCXqqhqC`qsyhk<-nlB
+z00f{QZvfK&|Nm#oZ0TQl`Yr$BIa6A at 16O26ud7H<QM=xl`toLKnz-3h at 9c9q&wm|X
+z{89I|WPyD!*M?gv?q`;L=2YFeXrJQNti4?}s!zFo=5CzeBxC69xA<zrjP<wUcCRh4
+ptUl-ZG<%a~#LwkIWv&q!KSCH7tQ8cJDiw+|GV?MN)RjY50RTb-xvT&H
+
+literal 0
+HcmV?d00001
+
+"""
+        self.scm.apply_patch(self._create_patch(git_binary_addition))
+        added = read_from_path('fizzbuzz7.gif')
+        self.assertEqual(512, len(added))
+        self.assertTrue(added.startswith('GIF89a'))
+        self.assertTrue('fizzbuzz7.gif' in self.scm.changed_files())
+
+        # The file already exists.
+        self.assertRaises(ScriptError, self.scm.apply_patch, self._create_patch(git_binary_addition))
+
+        git_binary_modification = """diff --git a/fizzbuzz7.gif b/fizzbuzz7.gif
+index 64a9532e7794fcd791f6f12157406d9060151690..323fae03f4606ea9991df8befbb2fca7
+GIT binary patch
+literal 7
+OcmYex&reD$;sO8*F9L)B
+
+literal 512
+zcmZ?wbhEHbRAx|MU|?iW{Kxc~?KofD;ckY;H+&5HnHl!!GQMD7h+sU{_)e9f^V3c?
+zhJP##HdZC#4K}7F68@!1jfWQg2daCm-gs#3|JREDT>c+pG4L<_2;w##WMO#ysPPap
+zLqpAf1OE938xAsSp4!5f-o><?VKe(#0jEcwfHGF4%M1^kRs14oVBp2ZEL{E1N<-zJ
+zsfLmOtKta;2_;2c#^S1-8cf<nb!QnGl>c!Xe6RXvrEtAWBvSDTgTO1j3vA31Puw!A
+zs(87q)j_mVDTqBo-P+03-P5mHCEnJ+x}YdCuS7#bCCyePUe(ynK+|4b-3qK)T?Z&)
+zYG+`tl4h?GZv_$t82}X4*DTE|$;{DEiPyF@)U-1+FaX++T9H{&%cag`W1|zVP@`%b
+zqiSkp6{BTpWTkCr!=<C6Q=?#~R8^JfrliAF6Q^gV9Iup8RqCXqqhqC`qsyhk<-nlB
+z00f{QZvfK&|Nm#oZ0TQl`Yr$BIa6A at 16O26ud7H<QM=xl`toLKnz-3h at 9c9q&wm|X
+z{89I|WPyD!*M?gv?q`;L=2YFeXrJQNti4?}s!zFo=5CzeBxC69xA<zrjP<wUcCRh4
+ptUl-ZG<%a~#LwkIWv&q!KSCH7tQ8cJDiw+|GV?MN)RjY50RTb-xvT&H
+
+"""
+        self.scm.apply_patch(self._create_patch(git_binary_modification))
+        modified = read_from_path('fizzbuzz7.gif')
+        self.assertEqual('foobar\n', modified)
+        self.assertTrue('fizzbuzz7.gif' in self.scm.changed_files())
+
+        # Applying the same modification should fail.
+        self.assertRaises(ScriptError, self.scm.apply_patch, self._create_patch(git_binary_modification))
+
+        git_binary_deletion = """diff --git a/fizzbuzz7.gif b/fizzbuzz7.gif
+deleted file mode 100644
+index 323fae0..0000000
+GIT binary patch
+literal 0
+HcmV?d00001
+
+literal 7
+OcmYex&reD$;sO8*F9L)B
+
+"""
+        self.scm.apply_patch(self._create_patch(git_binary_deletion))
+        self.assertFalse(os.path.exists('fizzbuzz7.gif'))
+        self.assertFalse('fizzbuzz7.gif' in self.scm.changed_files())
+
+        # Cannot delete again.
+        self.assertRaises(ScriptError, self.scm.apply_patch, self._create_patch(git_binary_deletion))
+
 
 class SVNTest(SCMTest):
 
@@ -387,6 +465,8 @@ Q1dTBx0AAAB42itg4GlgYJjGwMDDyODMxMDw34GBgQEAJPQDJA==
     def test_diff_for_revision(self):
         self._shared_test_diff_for_revision()
 
+    def test_svn_apply_git_patch(self):
+        self._shared_test_svn_apply_git_patch()
 
 class GitTest(SCMTest):
 
@@ -477,5 +557,8 @@ class GitTest(SCMTest):
     def test_diff_for_revision(self):
         self._shared_test_diff_for_revision()
 
+    def test_svn_apply_git_patch(self):
+        self._shared_test_svn_apply_git_patch()
+
 if __name__ == '__main__':
     unittest.main()
diff --git a/WebKitTools/Scripts/svn-apply b/WebKitTools/Scripts/svn-apply
index 4204625..0373aa5 100755
--- a/WebKitTools/Scripts/svn-apply
+++ b/WebKitTools/Scripts/svn-apply
@@ -55,7 +55,7 @@
 #   Notice a patch that's being applied at the "wrong level" and make it work anyway.
 #   Do a dry run on the whole patch and don't do anything if part of the patch is
 #       going to fail (probably too strict unless we exclude ChangeLog).
-#   Handle git-diff patches with binary changes
+#   Handle git-diff patches with binary delta
 
 use strict;
 use warnings;
@@ -75,6 +75,7 @@ sub addDirectoriesIfNeeded($);
 sub applyPatch($$;$);
 sub checksum($);
 sub handleBinaryChange($$);
+sub handleGitBinaryChange($$);
 sub isDirectoryEmptyForRemoval($);
 sub patch($);
 sub removeDirectoriesIfNeeded();
@@ -276,6 +277,39 @@ sub handleBinaryChange($$)
     }
 }
 
+sub handleGitBinaryChange($$)
+{
+    my ($fullPath, $contents) = @_;
+
+    my ($binaryChunkType, $binaryChunk, $reverseBinaryChunkType, $reverseBinaryChunk) = decodeGitBinaryPatch($contents, $fullPath);
+    # FIXME: support "delta" type.
+    die "only literal type is supported now" if ($binaryChunkType ne "literal" || $reverseBinaryChunkType ne "literal");
+
+    my $isFileAddition = $contents =~ /\nnew file mode \d+\n/;
+    my $isFileDeletion = $contents =~ /\ndeleted file mode \d+\n/;
+
+    my $originalContents = "";
+    if (open FILE, $fullPath) {
+        die "$fullPath already exists" if $isFileAddition;
+
+        $originalContents = join("", <FILE>);
+        close FILE;
+    }
+    die "Original content of $fullPath mismatches" if $originalContents ne $reverseBinaryChunk;
+
+    if ($isFileDeletion) {
+        scmRemove($fullPath);
+    } else {
+        # Addition or Modification
+        open FILE, ">", $fullPath or die "Failed to open $fullPath.";
+        print FILE $binaryChunk;
+        close FILE;
+        if ($isFileAddition) {
+            scmAdd($fullPath);
+        }
+    }
+}
+
 sub isDirectoryEmptyForRemoval($)
 {
     my ($dir) = @_;
@@ -310,12 +344,14 @@ sub patch($)
     my $deletion = 0;
     my $addition = 0;
     my $isBinary = 0;
+    my $isGitBinary = 0;
 
     $addition = 1 if ($patch =~ /\n--- .+\(revision 0\)\r?\n/ || $patch =~ /\n@@ -0,0 .* @@/) && !exists($copiedFiles{$fullPath});
     $deletion = 1 if $patch =~ /\n@@ .* \+0,0 @@/;
     $isBinary = 1 if $patch =~ /\nCannot display: file marked as a binary type\./;
+    $isGitBinary = 1 if $patch =~ /\nGIT binary patch\n/;
 
-    if (!$addition && !$deletion && !$isBinary) {
+    if (!$addition && !$deletion && !$isBinary && !$isGitBinary) {
         # Standard patch, patch tool can handle this.
         if (basename($fullPath) eq "ChangeLog") {
             my $changeLogDotOrigExisted = -f "${fullPath}.orig";
@@ -332,6 +368,9 @@ sub patch($)
         if ($isBinary) {
             # Binary change
             handleBinaryChange($fullPath, $patch);
+        } elsif ($isGitBinary) {
+            # Git binary change
+            handleGitBinaryChange($fullPath, $patch);
         } elsif ($deletion) {
             # Deletion
             applyPatch($patch, $fullPath, ["--force"]);

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list