From 924f2c3445bba28ec088af539a22885156ed7412 Mon Sep 17 00:00:00 2001 From: Gary O'Neall Date: Thu, 4 Mar 2021 12:47:48 -0800 Subject: [PATCH] Fix issue with very long var-rules causing unending REGEX backtracking Signed-off-by: Gary O'Neall --- TestFiles/GD.template.txt | 11 +++++++++ TestFiles/GD.txt | 24 +++++++++++++++++++ .../SpdxLicenseTemplateHelper.java | 16 +++++++++---- .../compare/LicenseCompareHelperTest.java | 7 ++++++ .../TestCompareTemplateOutputHandler.java | 13 ++++++++++ .../spdx/utility/compare/UnitTestHelper.java | 11 ++++++--- 6 files changed, 75 insertions(+), 7 deletions(-) create mode 100644 TestFiles/GD.template.txt create mode 100644 TestFiles/GD.txt diff --git a/TestFiles/GD.template.txt b/TestFiles/GD.template.txt new file mode 100644 index 000000000..6ed36424b --- /dev/null +++ b/TestFiles/GD.template.txt @@ -0,0 +1,11 @@ +<> Credits and license terms In order to resolve any possible confusion regarding the authorship of gd, the following copyright statement covers all of the authors who have required such a statement. If you are aware of any oversights in this copyright notice, please contact Pierre-A. Joye who will be pleased to correct them.<> <> + +Permission has been granted to copy, distribute and modify gd in any context without fee, including a commercial application, provided that this notice is present in user-accessible supporting documentation. + +This does not affect your ownership of the derived work itself, and the intent is to assure proper credit for the authors of gd, not to interfere with your productive use of gd. If you have questions, ask. "Derived works" includes all programs that utilize the library. Credit must be given in user-accessible documentation. + +This software is provided "AS IS." The copyright holders disclaim all warranties, either express or implied, including but not limited to implied warranties of merchantability and fitness for a particular purpose, with respect to this code and accompanying documentation. + +<> Although their code does not appear in the current release, the authors wish to thank David Koblas, David Rowley, and Hutchison Avenue Software Corporation for their prior contributions. + +<> \ No newline at end of file diff --git a/TestFiles/GD.txt b/TestFiles/GD.txt new file mode 100644 index 000000000..370e3df04 --- /dev/null +++ b/TestFiles/GD.txt @@ -0,0 +1,24 @@ +Credits and license terms + +In order to resolve any possible confusion regarding the authorship of gd, the following copyright statement covers all of the authors who have required such a statement. If you are aware of any oversights in this copyright notice, please contact Pierre-A. Joye who will be pleased to correct them. + + • Portions copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 by Cold Spring Harbor Laboratory. Funded under Grant P41-RR02188 by the National Institutes of Health. + • Portions copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 by Boutell.Com, Inc. + • Portions relating to GD2 format copyright 1999, 2000, 2001, 2002, 2003, 2004 Philip Warner. + • Portions relating to PNG copyright 1999, 2000, 2001, 2002, 2003, 2004 Greg Roelofs. + • Portions relating to gdttf.c copyright 1999, 2000, 2001, 2002, 2003, 2004 John Ellson (ellson@graphviz.org). + • Portions relating to gdft.c copyright 2001, 2002, 2003, 2004 John Ellson (ellson@graphviz.org). + • Portions copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Pierre-Alain Joye (pierre@libgd.org). + • Portions relating to JPEG and to color quantization copyright 2000, 2001, 2002, 2003, 2004, Doug Becker and copyright © 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Thomas G. Lane. This software is based in part on the work of the Independent JPEG Group. See the file README-JPEG.TXT for more information. + • Portions relating to GIF compression copyright 1989 by Jef Poskanzer and David Rowley, with modifications for thread safety by Thomas Boutell. + • Portions relating to GIF decompression copyright 1990, 1991, 1993 by David Koblas, with modifications for thread safety by Thomas Boutell. + • Portions relating to WBMP copyright 2000, 2001, 2002, 2003, 2004 Maurice Szmurlo and Johan Van den Brande. + • Portions relating to GIF animations copyright 2004 Jaakko Hyvätti (jaakko.hyvatti@iki.fi) + +Permission has been granted to copy, distribute and modify gd in any context without fee, including a commercial application, provided that this notice is present in user-accessible supporting documentation. + +This does not affect your ownership of the derived work itself, and the intent is to assure proper credit for the authors of gd, not to interfere with your productive use of gd. If you have questions, ask. “Derived works” includes all programs that utilize the library. Credit must be given in user-accessible documentation. + +This software is provided “AS IS.” The copyright holders disclaim all warranties, either express or implied, including but not limited to implied warranties of merchantability and fitness for a particular purpose, with respect to this code and accompanying documentation. + +Although their code does not appear in the current release, the authors wish to thank David Koblas, David Rowley, and Hutchison Avenue Software Corporation for their prior contributions. \ No newline at end of file diff --git a/src/main/java/org/spdx/licenseTemplate/SpdxLicenseTemplateHelper.java b/src/main/java/org/spdx/licenseTemplate/SpdxLicenseTemplateHelper.java index 6abda807d..5b16ffd57 100644 --- a/src/main/java/org/spdx/licenseTemplate/SpdxLicenseTemplateHelper.java +++ b/src/main/java/org/spdx/licenseTemplate/SpdxLicenseTemplateHelper.java @@ -33,7 +33,8 @@ public class SpdxLicenseTemplateHelper { static final String START_RULE = "<<"; static final String END_RULE = ">>"; - public static final Pattern RULE_PATTERN = Pattern.compile(START_RULE+"\\s*((beginOptional|endOptional|var)(.|\\s)*?)\\s*"+END_RULE); + public static final Pattern RULE_PATTERN = Pattern.compile(START_RULE+"\\s*(beginOptional|endOptional|var)"); + public static final Pattern END_RULE_PATTERN = Pattern.compile(END_RULE); private static final int SPACES_PER_TAB = 5; private static final int MAX_TABS = 4; private static final int[] PIXELS_PER_TAB = new int[] {20, 40, 60, 70}; @@ -47,16 +48,23 @@ public class SpdxLicenseTemplateHelper { public static void parseTemplate(String licenseTemplate, ILicenseTemplateOutputHandler templateOutputHandler) throws LicenseTemplateRuleException, LicenseParserException { Matcher ruleMatcher = RULE_PATTERN.matcher(licenseTemplate); + Matcher endRuleMatcher = END_RULE_PATTERN.matcher(licenseTemplate); int end = 0; int optionalNestLevel = 0; - while (ruleMatcher.find()) { + int start = 0; + while (ruleMatcher.find(start)) { // copy everything up to the start of the find String upToTheFind = licenseTemplate.substring(end, ruleMatcher.start()); if (!upToTheFind.trim().isEmpty()) { templateOutputHandler.text(upToTheFind); } - end = ruleMatcher.end(); - String ruleString = ruleMatcher.group(1); + if (!endRuleMatcher.find(ruleMatcher.end())) { + throw(new LicenseTemplateRuleException("Missing end of rule '>>' after text '"+upToTheFind+"'")); + } + end = endRuleMatcher.end(); + String ruleString = licenseTemplate.substring(ruleMatcher.start()+START_RULE.length(), end-END_RULE.length()); + start = end; + LicenseTemplateRule rule = new LicenseTemplateRule(ruleString); if (rule.getType() == LicenseTemplateRule.RuleType.VARIABLE) { templateOutputHandler.variableRule(rule); diff --git a/src/test/java/org/spdx/utility/compare/LicenseCompareHelperTest.java b/src/test/java/org/spdx/utility/compare/LicenseCompareHelperTest.java index 28606ddd6..aa47e3290 100644 --- a/src/test/java/org/spdx/utility/compare/LicenseCompareHelperTest.java +++ b/src/test/java/org/spdx/utility/compare/LicenseCompareHelperTest.java @@ -25,6 +25,7 @@ import java.util.Collection; import java.util.HashMap; import java.util.HashSet; +import java.util.List; import java.util.Map; import org.spdx.library.DefaultModelStore; @@ -55,6 +56,7 @@ public class LicenseCompareHelperTest extends TestCase { static final String BSD_PROTECTION_TEMPLATE = "TestFiles" + File.separator + "BSD-Protection.template.txt"; static final String EUPL_1_2_TEXT = "TestFiles" + File.separator + "EUPL-1.2.txt"; static final String EUPL_1_2_TEMPLATE = "TestFiles" + File.separator + "EUPL-1.2.template.txt"; + static final String GD_TEMPLATE = "TestFiles" + File.separator + "GD.template.txt"; /** * @throws java.lang.Exception @@ -706,4 +708,9 @@ public void testRegressionEUPL12() throws InvalidSPDXAnalysisException, SpdxComp DifferenceDescription diff = LicenseCompareHelper.isTextStandardLicense(lic, licText); assertFalse(diff.isDifferenceFound()); } + + public void testRegressionGD() throws InvalidSPDXAnalysisException, SpdxCompareException, IOException { + String templateText = UnitTestHelper.fileToText(GD_TEMPLATE); + List result = LicenseCompareHelper.getNonOptionalLicenseText(templateText, true); + } } diff --git a/src/test/java/org/spdx/utility/compare/TestCompareTemplateOutputHandler.java b/src/test/java/org/spdx/utility/compare/TestCompareTemplateOutputHandler.java index f70f66b99..7899b00b9 100644 --- a/src/test/java/org/spdx/utility/compare/TestCompareTemplateOutputHandler.java +++ b/src/test/java/org/spdx/utility/compare/TestCompareTemplateOutputHandler.java @@ -92,6 +92,8 @@ public class TestCompareTemplateOutputHandler { static final String BSD_2_CLAUSE_VIEW_TEMPLATE = "TestFiles" + File.separator + "BSD-2-Clause-Views.template.txt"; static final String EUPL_1_2_TEXT = "TestFiles" + File.separator + "EUPL-1.2.txt"; static final String EUPL_1_2_TEMPLATE = "TestFiles" + File.separator + "EUPL-1.2.template.txt"; + static final String GD_TEXT = "TestFiles" + File.separator + "GD.txt"; + static final String GD_TEMPLATE = "TestFiles" + File.separator + "GD.template.txt"; /** * @throws java.lang.Exception @@ -600,6 +602,17 @@ public void testRegressionEUPL12() throws IOException, LicenseTemplateRuleExcept } } + @Test + public void testRegressionGD() throws IOException, LicenseTemplateRuleException, LicenseParserException { + String compareText = UnitTestHelper.fileToText(GD_TEXT); + String templateText = UnitTestHelper.fileToText(GD_TEMPLATE); + CompareTemplateOutputHandler templateOutputHandler = new CompareTemplateOutputHandler(compareText); + SpdxLicenseTemplateHelper.parseTemplate(templateText, templateOutputHandler); + if (!templateOutputHandler.matches()) { + fail(templateOutputHandler.getDifferences().getDifferenceMessage()); + } + } + @Test public void testCompareHttps() throws IOException, LicenseTemplateRuleException, LicenseParserException { String compareText = UnitTestHelper.fileToText(AGPL_3_0_ONLY_TEXT); diff --git a/src/test/java/org/spdx/utility/compare/UnitTestHelper.java b/src/test/java/org/spdx/utility/compare/UnitTestHelper.java index 25d4642a1..88836d019 100644 --- a/src/test/java/org/spdx/utility/compare/UnitTestHelper.java +++ b/src/test/java/org/spdx/utility/compare/UnitTestHelper.java @@ -72,9 +72,14 @@ public static boolean isArraysEqual(Object[] a1, */ public static String fileToText(String filePath) throws IOException { StringBuilder sb = new StringBuilder(); - for (String s:Files.readAllLines(Paths.get(filePath), StandardCharsets.UTF_8)) { - sb.append(s); - sb.append("\n"); + List lines = Files.readAllLines(Paths.get(filePath), StandardCharsets.UTF_8); + if (lines.size() == 0) { + return ""; + } + sb.append(lines.get(0)); + for (int i = 1; i < lines.size(); i++) { + sb.append("\n"); + sb.append(lines.get(i)); } return sb.toString(); }