Fix JsonManipulator handling of package links, fixes #1465
parent
bebe86262a
commit
3b48a1fea6
|
@ -49,37 +49,47 @@ class JsonManipulator
|
||||||
|
|
||||||
public function addLink($type, $package, $constraint)
|
public function addLink($type, $package, $constraint)
|
||||||
{
|
{
|
||||||
// no link of that type yet
|
$data = @json_decode($this->contents, true);
|
||||||
if (!preg_match('#"'.$type.'":\s*\{#', $this->contents)) {
|
|
||||||
$this->addMainKey($type, array($package => $constraint));
|
|
||||||
|
|
||||||
return true;
|
// abort if the file is not parseable
|
||||||
}
|
if (null === $data) {
|
||||||
|
|
||||||
$linksRegex = '#("'.$type.'":\s*\{)([^}]+)(\})#s';
|
|
||||||
if (!preg_match($linksRegex, $this->contents, $match)) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$links = $match[2];
|
// no link of that type yet
|
||||||
$packageRegex = str_replace('/', '\\\\?/', preg_quote($package));
|
if (!isset($data[$type])) {
|
||||||
|
return $this->addMainKey($type, array($package => $constraint));
|
||||||
// link exists already
|
|
||||||
if (preg_match('{"'.$packageRegex.'"\s*:}i', $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].'$#',
|
|
||||||
addcslashes(',' . $this->newline . $this->indent . $this->indent . JsonFile::encode($package).': '.JsonFile::encode($constraint) . $match[1], '\\'),
|
|
||||||
$links
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
// links empty
|
|
||||||
$links = $this->newline . $this->indent . $this->indent . JsonFile::encode($package).': '.JsonFile::encode($constraint) . $links;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->contents = preg_replace($linksRegex, addcslashes('${1}'.$links.'$3', '\\'), $this->contents);
|
$regex = '{^(\s*\{\s*(?:'.self::$JSON_STRING.'\s*:\s*'.self::$JSON_VALUE.'\s*,\s*)*?)'.
|
||||||
|
'('.preg_quote(JsonFile::encode($type)).'\s*:\s*)('.self::$JSON_VALUE.')(.*)}s';
|
||||||
|
if (!preg_match($regex, $this->contents, $matches)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$links = $matches[3];
|
||||||
|
|
||||||
|
if (isset($data[$type][$package])) {
|
||||||
|
// update existing link
|
||||||
|
$packageRegex = str_replace('/', '\\\\?/', preg_quote($package));
|
||||||
|
$links = preg_replace('{"'.$packageRegex.'"(\s*:\s*)'.self::$JSON_STRING.'}i', addcslashes(JsonFile::encode($package).'${1}"'.$constraint.'"', '\\'), $links);
|
||||||
|
} else {
|
||||||
|
if (preg_match('#^\s*\{\s*\S+.*?(\s*\}\s*)$#', $links, $match)) {
|
||||||
|
// link missing but non empty links
|
||||||
|
$links = preg_replace(
|
||||||
|
'{'.preg_quote($match[1]).'$}',
|
||||||
|
addcslashes(',' . $this->newline . $this->indent . $this->indent . JsonFile::encode($package).': '.JsonFile::encode($constraint) . $match[1], '\\'),
|
||||||
|
$links
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
// links empty
|
||||||
|
$links = '{' . $this->newline .
|
||||||
|
$this->indent . $this->indent . JsonFile::encode($package).': '.JsonFile::encode($constraint) . $this->newline .
|
||||||
|
$this->indent . '}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->contents = $matches[1] . $matches[2] . $links . $matches[4];
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -127,7 +137,7 @@ class JsonManipulator
|
||||||
$children = $match[2];
|
$children = $match[2];
|
||||||
|
|
||||||
// invalid match due to un-regexable content, abort
|
// invalid match due to un-regexable content, abort
|
||||||
if (!json_decode('{'.$children.'}')) {
|
if (!@json_decode('{'.$children.'}')) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,7 +200,7 @@ class JsonManipulator
|
||||||
$children = $match[2];
|
$children = $match[2];
|
||||||
|
|
||||||
// invalid match due to un-regexable content, abort
|
// invalid match due to un-regexable content, abort
|
||||||
if (!json_decode('{'.$children.'}')) {
|
if (!@json_decode('{'.$children.'}')) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -256,7 +266,7 @@ class JsonManipulator
|
||||||
'('.preg_quote(JsonFile::encode($key)).'\s*:\s*'.self::$JSON_VALUE.')(.*)}s';
|
'('.preg_quote(JsonFile::encode($key)).'\s*:\s*'.self::$JSON_VALUE.')(.*)}s';
|
||||||
if (preg_match($regex, $this->contents, $matches)) {
|
if (preg_match($regex, $this->contents, $matches)) {
|
||||||
// invalid match due to un-regexable content, abort
|
// invalid match due to un-regexable content, abort
|
||||||
if (!json_decode('{'.$matches[2].'}')) {
|
if (!@json_decode('{'.$matches[2].'}')) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -126,6 +126,67 @@ class JsonManipulatorTest extends \PHPUnit_Framework_TestCase
|
||||||
"vendor/baz": "qux"
|
"vendor/baz": "qux"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
'
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'{
|
||||||
|
"require": {
|
||||||
|
"foo": "bar"
|
||||||
|
},
|
||||||
|
"repositories": [{
|
||||||
|
"type": "package",
|
||||||
|
"package": {
|
||||||
|
"require": {
|
||||||
|
"foo": "bar"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
}',
|
||||||
|
'require',
|
||||||
|
'foo',
|
||||||
|
'qux',
|
||||||
|
'{
|
||||||
|
"require": {
|
||||||
|
"foo": "qux"
|
||||||
|
},
|
||||||
|
"repositories": [{
|
||||||
|
"type": "package",
|
||||||
|
"package": {
|
||||||
|
"require": {
|
||||||
|
"foo": "bar"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
'
|
||||||
|
),
|
||||||
|
array(
|
||||||
|
'{
|
||||||
|
"repositories": [{
|
||||||
|
"type": "package",
|
||||||
|
"package": {
|
||||||
|
"require": {
|
||||||
|
"foo": "bar"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
}',
|
||||||
|
'require',
|
||||||
|
'foo',
|
||||||
|
'qux',
|
||||||
|
'{
|
||||||
|
"repositories": [{
|
||||||
|
"type": "package",
|
||||||
|
"package": {
|
||||||
|
"require": {
|
||||||
|
"foo": "bar"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
"require": {
|
||||||
|
"foo": "qux"
|
||||||
|
}
|
||||||
|
}
|
||||||
'
|
'
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in New Issue