Browse Source

Fix json manipulator handling of escaped backslashes, fixes #1588

Jordi Boggiano 12 years ago
parent
commit
e348642aa7

+ 7 - 11
src/Composer/Json/JsonManipulator.php

@@ -58,12 +58,12 @@ class JsonManipulator
 
         // link exists already
         if (preg_match('{"'.$packageRegex.'"\s*:}i', $links)) {
-            $links = preg_replace('{"'.$packageRegex.'"(\s*:\s*)"[^"]+"}i', JsonFile::encode($package).'${1}"'.$constraint.'"', $links);
+            $links = preg_replace('{"'.$packageRegex.'"(\s*:\s*)"[^"]+"}i', addcslashes(JsonFile::encode($package).'${1}"'.$constraint.'"', '\\'), $links);
         } elseif (preg_match('#[^\s](\s*)$#', $links, $match)) {
             // link missing but non empty links
             $links = preg_replace(
                 '#'.$match[1].'$#',
-                ',' . $this->newline . $this->indent . $this->indent . JsonFile::encode($package).': '.JsonFile::encode($constraint) . $match[1],
+                addcslashes(',' . $this->newline . $this->indent . $this->indent . JsonFile::encode($package).': '.JsonFile::encode($constraint) . $match[1], '\\'),
                 $links
             );
         } else {
@@ -71,7 +71,7 @@ class JsonManipulator
             $links = $this->newline . $this->indent . $this->indent . JsonFile::encode($package).': '.JsonFile::encode($constraint) . $links;
         }
 
-        $this->contents = preg_replace($linksRegex, '${1}'.$links.'$3', $this->contents);
+        $this->contents = preg_replace($linksRegex, addcslashes('${1}'.$links.'$3', '\\'), $this->contents);
 
         return true;
     }
@@ -144,7 +144,7 @@ class JsonManipulator
             // child missing but non empty children
             $children = preg_replace(
                 '#'.$match[1].'$#',
-                ',' . $this->newline . $this->indent . $this->indent . JsonFile::encode($name).': '.$this->format($value, 1) . $match[1],
+                addcslashes(',' . $this->newline . $this->indent . $this->indent . JsonFile::encode($name).': '.$this->format($value, 1) . $match[1], '\\'),
                 $children
             );
         } else {
@@ -156,7 +156,7 @@ class JsonManipulator
             $children = $this->newline . $this->indent . $this->indent . JsonFile::encode($name).': '.$this->format($value, 1) . $children;
         }
 
-        $this->contents = preg_replace($nodeRegex, '${1}'.$children.'$3', $this->contents);
+        $this->contents = preg_replace($nodeRegex, addcslashes('${1}'.$children.'$3', '\\'), $this->contents);
 
         return true;
     }
@@ -225,10 +225,6 @@ class JsonManipulator
             return true;
         }
 
-        if ($subName !== null) {
-
-        }
-
         $that = $this;
         $this->contents = preg_replace_callback($nodeRegex, function ($matches) use ($that, $name, $subName, $childrenClean) {
             if ($subName !== null) {
@@ -248,13 +244,13 @@ class JsonManipulator
         if (preg_match('#[^{\s](\s*)\}$#', $this->contents, $match)) {
             $this->contents = preg_replace(
                 '#'.$match[1].'\}$#',
-                ',' . $this->newline . $this->indent . JsonFile::encode($key). ': '. $content . $this->newline . '}',
+                addcslashes(',' . $this->newline . $this->indent . JsonFile::encode($key). ': '. $content . $this->newline . '}', '\\'),
                 $this->contents
             );
         } else {
             $this->contents = preg_replace(
                 '#\}$#',
-                $this->indent . JsonFile::encode($key). ': '.$content . $this->newline . '}',
+                addcslashes($this->indent . JsonFile::encode($key). ': '.$content . $this->newline . '}', '\\'),
                 $this->contents
             );
         }

+ 7 - 1
tests/Composer/Test/Json/JsonFileTest.php

@@ -179,12 +179,18 @@ class JsonFileTest extends \PHPUnit_Framework_TestCase
 
     public function testEscapedSlashes()
     {
-
         $data = "\\/foo";
 
         $this->assertJsonFormat('"\\\\\\/foo"', $data, 0);
     }
 
+    public function testEscapedBackslashes()
+    {
+        $data = "a\\b";
+
+        $this->assertJsonFormat('"a\\\\b"', $data, 0);
+    }
+
     public function testEscapedUnicode()
     {
         $data = "ƌ";

+ 16 - 0
tests/Composer/Test/Json/JsonManipulatorTest.php

@@ -392,6 +392,22 @@ class JsonManipulatorTest extends \PHPUnit_Framework_TestCase
 ', $manipulator->getContents());
     }
 
+    public function testAddConfigSettingEscapes()
+    {
+        $manipulator = new JsonManipulator('{
+    "config": {
+    }
+}');
+
+        $this->assertTrue($manipulator->addConfigSetting('test', 'a\b'));
+        $this->assertEquals('{
+    "config": {
+        "test": "a\\\\b"
+    }
+}
+', $manipulator->getContents());
+    }
+
     public function testAddConfigSettingCanAdd()
     {
         $manipulator = new JsonManipulator('{