From 656dac3770b11b084ee570bc5bc0cd9107d20c39 Mon Sep 17 00:00:00 2001 From: Sai Asish Y Date: Thu, 9 Jul 2026 18:05:41 -0700 Subject: [PATCH] Fix nil-pointer panic on expression ending in an open parenthesis Signed-off-by: Sai Asish Y --- spdxexp/parse.go | 17 ++++++++++++++++- spdxexp/parse_test.go | 3 +++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/spdxexp/parse.go b/spdxexp/parse.go index f66de71..13e12a2 100644 --- a/spdxexp/parse.go +++ b/spdxexp/parse.go @@ -281,6 +281,10 @@ func (t *tokenStream) parseLicenseRef() *node { ref := referenceNodePartial{documentRef: "", hasDocumentRef: false, licenseRef: ""} token := t.peek() + if token == nil { + // end of stream, so no license reference to parse + return nil + } if token.role == documentRefToken { ref.documentRef = token.value ref.hasDocumentRef = true @@ -294,6 +298,13 @@ func (t *tokenStream) parseLicenseRef() *node { } token = t.peek() + if token == nil && ref.hasDocumentRef { + t.err = errors.New("expected 'LicenseRef-...' after 'DocumentRef-...'") + return nil + } else if token == nil { + // not found is not an error as long as DocumentRef and : weren't the previous tokens + return nil + } if token.role != licenseRefToken && ref.hasDocumentRef { t.err = errors.New("expected 'LicenseRef-...' after 'DocumentRef-...'") return nil @@ -315,7 +326,7 @@ func (t *tokenStream) parseLicenseRef() *node { // an error is returned. Advances the index if a valid license is found. func (t *tokenStream) parseLicense() *node { token := t.peek() - if token.role != licenseToken { + if token == nil || token.role != licenseToken { return nil } t.next() @@ -361,6 +372,10 @@ func (t *tokenStream) parseLicense() *node { // Advances the index if the operator is found. func (t *tokenStream) parseOperator(operator string) *string { token := t.peek() + if token == nil { + // end of stream, so the requested operator is not present + return nil + } if token.role == operatorToken && token.value == operator { t.next() return &(token.value) diff --git a/spdxexp/parse_test.go b/spdxexp/parse_test.go index 1d19abe..a4db4a0 100644 --- a/spdxexp/parse_test.go +++ b/spdxexp/parse_test.go @@ -45,6 +45,9 @@ func TestParse(t *testing.T) { {"invalid license", "NON-EXISTENT-LICENSE", nil, "", errors.New("unknown license 'NON-EXISTENT-LICENSE' at offset 0")}, + {"dangling open parenthesis", "(", nil, "", + errors.New("expected node, but found none")}, + {"OR Expression", "MIT OR Apache-2.0", &node{ role: expressionNode,