Revert "apply a regex solution instead of tokenizer"
This reverts commit 33a7305e22c8d4e2ce38586855fd3d4b7b2af3dd.pull/4208/head
parent
b5d286e27b
commit
4019f7bb44
|
@ -192,69 +192,115 @@ class SpdxLicense
|
||||||
* @param string $license
|
* @param string $license
|
||||||
*
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
*
|
|
||||||
* @throws \RuntimeException
|
* @throws \RuntimeException
|
||||||
*/
|
*/
|
||||||
private function isValidLicenseString($license)
|
private function isValidLicenseString($license)
|
||||||
{
|
{
|
||||||
$licenses = array_map('preg_quote', array_keys($this->licenses));
|
$tokens = array(
|
||||||
sort($licenses);
|
'po' => '\(',
|
||||||
$licenses = array_reverse($licenses);
|
'pc' => '\)',
|
||||||
$licenses = implode('|', $licenses);
|
'op' => '(?:or|OR|and|AND)',
|
||||||
|
'wi' => '(?:with|WITH)',
|
||||||
|
'lix' => '(?:NONE|NOASSERTION)',
|
||||||
|
'lir' => 'LicenseRef-\d+',
|
||||||
|
'lic' => '[-_.a-zA-Z0-9]{3,}\+?',
|
||||||
|
'ws' => '\s+',
|
||||||
|
'_' => '.',
|
||||||
|
);
|
||||||
|
|
||||||
$exceptions = array_map('preg_quote', array_keys($this->exceptions));
|
$next = function () use ($license, $tokens) {
|
||||||
sort($exceptions);
|
static $offset = 0;
|
||||||
$exceptions = array_reverse($exceptions);
|
|
||||||
$exceptions = implode('|', $exceptions);
|
|
||||||
|
|
||||||
$regex = "{
|
if ($offset >= strlen($license)) {
|
||||||
(?(DEFINE)
|
return null;
|
||||||
# idstring: 1*( ALPHA / DIGIT / - / . )
|
}
|
||||||
(?<idstring>[\pL\pN\-\.]{1,})
|
|
||||||
|
|
||||||
# license-id: taken from list
|
foreach ($tokens as $name => $token) {
|
||||||
(?<licenseid>${licenses})
|
if (false === $r = preg_match('{' . $token . '}', $license, $matches, PREG_OFFSET_CAPTURE, $offset)) {
|
||||||
|
throw new \RuntimeException('Pattern for token %s failed (regex error).', $name);
|
||||||
|
}
|
||||||
|
if ($r === 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ($matches[0][1] !== $offset) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$offset += strlen($matches[0][0]);
|
||||||
|
|
||||||
# license-exception-id: taken from list
|
return array($name, $matches[0][0]);
|
||||||
(?<licenseexceptionid>${exceptions})
|
}
|
||||||
|
|
||||||
# license-ref: [DocumentRef-1*(idstring):]LicenseRef-1*(idstring)
|
throw new \RuntimeException(
|
||||||
(?<licenseref>(?:DocumentRef-(?&idstring):)?LicenseRef-(?&idstring))
|
'At least the last pattern needs to match, but it did not (dot-match-all is missing?).'
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
# simple-expresssion: license-id / license-id+ / license-ref
|
$open = 0;
|
||||||
(?<simple_expression>(?&licenseid)\+? | (?&licenseid) | (?&licenseref))
|
$with = false;
|
||||||
|
$require = true;
|
||||||
|
$lastop = null;
|
||||||
|
|
||||||
# compound expression: 1*(
|
while (list($token, $string) = $next()) {
|
||||||
# simple-expression /
|
switch ($token) {
|
||||||
# simple-expression WITH license-exception-id /
|
case 'po':
|
||||||
# compound-expression AND compound-expression /
|
if ($open || !$require || $with) {
|
||||||
# compound-expression OR compound-expression
|
return false;
|
||||||
# ) / ( compound-expression ) )
|
}
|
||||||
(?<compound_head>
|
$open = 1;
|
||||||
(?&simple_expression) ( \s+ (?:with|WITH) \s+ (?&licenseexceptionid))?
|
break;
|
||||||
| \( \s* (?&compound_expression) \s*\)
|
case 'pc':
|
||||||
)
|
if ($open !== 1 || $require || !$lastop || $with) {
|
||||||
(?<compound_expression>
|
return false;
|
||||||
(?&compound_head) (?: \s+ (?:and|AND|or|OR) \s+ (?&compound_expression))?
|
}
|
||||||
)
|
$open = 2;
|
||||||
|
break;
|
||||||
# license-expression: 1*1(simple-expression / compound-expression)
|
case 'op':
|
||||||
(?<license_expression>NONE | NOASSERTION | (?&compound_expression) | (?&simple_expression))
|
if ($require || !$open || $with) {
|
||||||
) # end of define
|
return false;
|
||||||
|
}
|
||||||
^(?&license_expression)$
|
$lastop || $lastop = $string;
|
||||||
}x";
|
if ($lastop !== $string) {
|
||||||
|
return false;
|
||||||
$match = preg_match($regex, $license);
|
}
|
||||||
|
$require = true;
|
||||||
if (0 === $match) {
|
break;
|
||||||
return false;
|
case 'wi':
|
||||||
|
$with = true;
|
||||||
|
break;
|
||||||
|
case 'lix':
|
||||||
|
if ($open || $with) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
goto lir;
|
||||||
|
case 'lic':
|
||||||
|
if ($with && $this->isValidExceptionIdentifier($string)) {
|
||||||
|
$require = true;
|
||||||
|
$with = false;
|
||||||
|
goto lir;
|
||||||
|
}
|
||||||
|
if ($with) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!$this->isValidLicenseIdentifier(rtrim($string, '+'))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Fall-through intended
|
||||||
|
case 'lir':
|
||||||
|
lir:
|
||||||
|
if (!$require) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
$require = false;
|
||||||
|
break;
|
||||||
|
case 'ws':
|
||||||
|
break;
|
||||||
|
case '_':
|
||||||
|
return false;
|
||||||
|
default:
|
||||||
|
throw new \RuntimeException(sprintf('Unparsed token: %s.', print_r($token, true)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (false === $match) {
|
return !($open % 2 || $require || $with);
|
||||||
throw new \RuntimeException('Regex failed to compile/run.');
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,6 @@ class SpdxLicenseTest extends TestCase
|
||||||
"GPL-2.0 with Autoconf-exception-2.0",
|
"GPL-2.0 with Autoconf-exception-2.0",
|
||||||
"GPL-2.0 WITH Autoconf-exception-2.0",
|
"GPL-2.0 WITH Autoconf-exception-2.0",
|
||||||
"GPL-2.0+ WITH Autoconf-exception-2.0",
|
"GPL-2.0+ WITH Autoconf-exception-2.0",
|
||||||
"(GPL-3.0 and GPL-2.0 or GPL-3.0+)",
|
|
||||||
),
|
),
|
||||||
$identifiers
|
$identifiers
|
||||||
);
|
);
|
||||||
|
@ -58,6 +57,7 @@ class SpdxLicenseTest extends TestCase
|
||||||
array(array()),
|
array(array()),
|
||||||
array("The system pwns you"),
|
array("The system pwns you"),
|
||||||
array("()"),
|
array("()"),
|
||||||
|
array("(MIT)"),
|
||||||
array("(MIT"),
|
array("(MIT"),
|
||||||
array("MIT)"),
|
array("MIT)"),
|
||||||
array("MIT NONE"),
|
array("MIT NONE"),
|
||||||
|
@ -66,6 +66,8 @@ class SpdxLicenseTest extends TestCase
|
||||||
array("(MIT and MIT) MIT"),
|
array("(MIT and MIT) MIT"),
|
||||||
array(array("LGPL-2.0", "The system pwns you")),
|
array(array("LGPL-2.0", "The system pwns you")),
|
||||||
array("and GPL-3.0+"),
|
array("and GPL-3.0+"),
|
||||||
|
array("EUDatagrid and GPL-3.0+"),
|
||||||
|
array("(GPL-3.0 and GPL-2.0 or GPL-3.0+)"),
|
||||||
array("(EUDatagrid and GPL-3.0+ and )"),
|
array("(EUDatagrid and GPL-3.0+ and )"),
|
||||||
array("(EUDatagrid xor GPL-3.0+)"),
|
array("(EUDatagrid xor GPL-3.0+)"),
|
||||||
array("(MIT Or MIT)"),
|
array("(MIT Or MIT)"),
|
||||||
|
|
Loading…
Reference in New Issue