1// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later 2package parser2v3 3 4import ( 5 "fmt" 6 "testing" 7 8 "github.com/spdx/tools-golang/spdx/common" 9 "github.com/spdx/tools-golang/spdx/v2_3" 10) 11 12// ===== Parser package section state change tests ===== 13func TestParser2_3PackageStartsNewPackageAfterParsingPackageNameTag(t *testing.T) { 14 // create the first package 15 pkgOldName := "p1" 16 17 parser := tvParser2_3{ 18 doc: &v2_3.Document{Packages: []*v2_3.Package{}}, 19 st: psPackage2_3, 20 pkg: &v2_3.Package{PackageName: pkgOldName, PackageSPDXIdentifier: "p1"}, 21 } 22 pkgOld := parser.pkg 23 parser.doc.Packages = append(parser.doc.Packages, pkgOld) 24 // the Document's Packages should have this one only 25 if parser.doc.Packages[0] != pkgOld { 26 t.Errorf("expected package %v, got %v", pkgOld, parser.doc.Packages[0]) 27 } 28 if len(parser.doc.Packages) != 1 { 29 t.Errorf("expected 1 package, got %d", len(parser.doc.Packages)) 30 } 31 32 // now add a new package 33 pkgName := "p2" 34 err := parser.parsePair2_3("PackageName", pkgName) 35 if err != nil { 36 t.Errorf("got error when calling parsePair2_3: %v", err) 37 } 38 // state should be correct 39 if parser.st != psPackage2_3 { 40 t.Errorf("expected state to be %v, got %v", psPackage2_3, parser.st) 41 } 42 // and a package should be created 43 if parser.pkg == nil { 44 t.Fatalf("parser didn't create new package") 45 } 46 // and it should not be pkgOld 47 if parser.pkg == pkgOld { 48 t.Errorf("expected new package, got pkgOld") 49 } 50 // and the package name should be as expected 51 if parser.pkg.PackageName != pkgName { 52 t.Errorf("expected package name %s, got %s", pkgName, parser.pkg.PackageName) 53 } 54 // and the package should default to true for FilesAnalyzed 55 if parser.pkg.FilesAnalyzed != true { 56 t.Errorf("expected FilesAnalyzed to default to true, got false") 57 } 58 if parser.pkg.IsFilesAnalyzedTagPresent != false { 59 t.Errorf("expected IsFilesAnalyzedTagPresent to default to false, got true") 60 } 61 // and the Document's Packages should still be of size 1 and have pkgOld only 62 if parser.doc.Packages[0] != pkgOld { 63 t.Errorf("Expected package %v, got %v", pkgOld, parser.doc.Packages[0]) 64 } 65 if len(parser.doc.Packages) != 1 { 66 t.Errorf("expected 1 package, got %d", len(parser.doc.Packages)) 67 } 68} 69 70func TestParser2_3PackageStartsNewPackageAfterParsingPackageNameTagWhileInUnpackaged(t *testing.T) { 71 // pkg is nil, so that Files appearing before the first PackageName tag 72 // are added to Files instead of Packages 73 parser := tvParser2_3{ 74 doc: &v2_3.Document{Packages: []*v2_3.Package{}}, 75 st: psFile2_3, 76 pkg: nil, 77 } 78 // the Document's Packages should be empty 79 if len(parser.doc.Packages) != 0 { 80 t.Errorf("Expected zero packages, got %d", len(parser.doc.Packages)) 81 } 82 83 // now add a new package 84 pkgName := "p2" 85 err := parser.parsePair2_3("PackageName", pkgName) 86 if err != nil { 87 t.Errorf("got error when calling parsePair2_3: %v", err) 88 } 89 // state should be correct 90 if parser.st != psPackage2_3 { 91 t.Errorf("expected state to be %v, got %v", psPackage2_3, parser.st) 92 } 93 // and a package should be created 94 if parser.pkg == nil { 95 t.Fatalf("parser didn't create new package") 96 } 97 // and the package name should be as expected 98 if parser.pkg.PackageName != pkgName { 99 t.Errorf("expected package name %s, got %s", pkgName, parser.pkg.PackageName) 100 } 101 // and the package should default to true for FilesAnalyzed 102 if parser.pkg.FilesAnalyzed != true { 103 t.Errorf("expected FilesAnalyzed to default to true, got false") 104 } 105 if parser.pkg.IsFilesAnalyzedTagPresent != false { 106 t.Errorf("expected IsFilesAnalyzedTagPresent to default to false, got true") 107 } 108 // and the Document's Packages should be of size 0, because the prior was 109 // unpackaged files and this one won't be added until an SPDXID is seen 110 if len(parser.doc.Packages) != 0 { 111 t.Errorf("Expected %v packages in doc, got %v", 0, len(parser.doc.Packages)) 112 } 113} 114 115func TestParser2_3PackageMovesToFileAfterParsingFileNameTag(t *testing.T) { 116 parser := tvParser2_3{ 117 doc: &v2_3.Document{Packages: []*v2_3.Package{}}, 118 st: psPackage2_3, 119 pkg: &v2_3.Package{PackageName: "p1", PackageSPDXIdentifier: "p1"}, 120 } 121 parser.doc.Packages = append(parser.doc.Packages, parser.pkg) 122 pkgCurrent := parser.pkg 123 124 err := parser.parsePair2_3("FileName", "testFile") 125 if err != nil { 126 t.Errorf("got error when calling parsePair2_3: %v", err) 127 } 128 // state should be correct 129 if parser.st != psFile2_3 { 130 t.Errorf("expected state to be %v, got %v", psFile2_3, parser.st) 131 } 132 // and current package should remain what it was 133 if parser.pkg != pkgCurrent { 134 t.Fatalf("expected package to remain %v, got %v", pkgCurrent, parser.pkg) 135 } 136} 137 138func TestParser2_3PackageMovesToOtherLicenseAfterParsingLicenseIDTag(t *testing.T) { 139 parser := tvParser2_3{ 140 doc: &v2_3.Document{Packages: []*v2_3.Package{}}, 141 st: psPackage2_3, 142 pkg: &v2_3.Package{PackageName: "p1", PackageSPDXIdentifier: "p1"}, 143 } 144 parser.doc.Packages = append(parser.doc.Packages, parser.pkg) 145 146 err := parser.parsePair2_3("LicenseID", "LicenseRef-TestLic") 147 if err != nil { 148 t.Errorf("got error when calling parsePair2_3: %v", err) 149 } 150 if parser.st != psOtherLicense2_3 { 151 t.Errorf("expected state to be %v, got %v", psOtherLicense2_3, parser.st) 152 } 153} 154 155func TestParser2_3PackageMovesToReviewAfterParsingReviewerTag(t *testing.T) { 156 parser := tvParser2_3{ 157 doc: &v2_3.Document{Packages: []*v2_3.Package{}}, 158 st: psPackage2_3, 159 pkg: &v2_3.Package{PackageName: "p1", PackageSPDXIdentifier: "p1"}, 160 } 161 parser.doc.Packages = append(parser.doc.Packages, parser.pkg) 162 163 err := parser.parsePair2_3("Reviewer", "Person: John Doe") 164 if err != nil { 165 t.Errorf("got error when calling parsePair2_3: %v", err) 166 } 167 if parser.st != psReview2_3 { 168 t.Errorf("expected state to be %v, got %v", psReview2_3, parser.st) 169 } 170} 171 172func TestParser2_3PackageStaysAfterParsingRelationshipTags(t *testing.T) { 173 parser := tvParser2_3{ 174 doc: &v2_3.Document{Packages: []*v2_3.Package{}}, 175 st: psPackage2_3, 176 pkg: &v2_3.Package{PackageName: "p1", PackageSPDXIdentifier: "p1"}, 177 } 178 parser.doc.Packages = append(parser.doc.Packages, parser.pkg) 179 180 err := parser.parsePair2_3("Relationship", "SPDXRef-blah CONTAINS SPDXRef-blah-else") 181 if err != nil { 182 t.Errorf("got error when calling parsePair2_3: %v", err) 183 } 184 // state should remain unchanged 185 if parser.st != psPackage2_3 { 186 t.Errorf("expected state to be %v, got %v", psPackage2_3, parser.st) 187 } 188 189 err = parser.parsePair2_3("RelationshipComment", "blah") 190 if err != nil { 191 t.Errorf("got error when calling parsePair2_3: %v", err) 192 } 193 // state should still remain unchanged 194 if parser.st != psPackage2_3 { 195 t.Errorf("expected state to be %v, got %v", psPackage2_3, parser.st) 196 } 197} 198 199func TestParser2_3PackageStaysAfterParsingAnnotationTags(t *testing.T) { 200 parser := tvParser2_3{ 201 doc: &v2_3.Document{Packages: []*v2_3.Package{}}, 202 st: psPackage2_3, 203 pkg: &v2_3.Package{PackageName: "p1", PackageSPDXIdentifier: "p1"}, 204 } 205 parser.doc.Packages = append(parser.doc.Packages, parser.pkg) 206 207 err := parser.parsePair2_3("Annotator", "Person: John Doe ()") 208 if err != nil { 209 t.Errorf("got error when calling parsePair2_3: %v", err) 210 } 211 if parser.st != psPackage2_3 { 212 t.Errorf("parser is in state %v, expected %v", parser.st, psPackage2_3) 213 } 214 215 err = parser.parsePair2_3("AnnotationDate", "2018-09-15T00:36:00Z") 216 if err != nil { 217 t.Errorf("got error when calling parsePair2_3: %v", err) 218 } 219 if parser.st != psPackage2_3 { 220 t.Errorf("parser is in state %v, expected %v", parser.st, psPackage2_3) 221 } 222 223 err = parser.parsePair2_3("AnnotationType", "REVIEW") 224 if err != nil { 225 t.Errorf("got error when calling parsePair2_3: %v", err) 226 } 227 if parser.st != psPackage2_3 { 228 t.Errorf("parser is in state %v, expected %v", parser.st, psPackage2_3) 229 } 230 231 err = parser.parsePair2_3("SPDXREF", "SPDXRef-45") 232 if err != nil { 233 t.Errorf("got error when calling parsePair2_3: %v", err) 234 } 235 if parser.st != psPackage2_3 { 236 t.Errorf("parser is in state %v, expected %v", parser.st, psPackage2_3) 237 } 238 239 err = parser.parsePair2_3("AnnotationComment", "i guess i had something to say about this package") 240 if err != nil { 241 t.Errorf("got error when calling parsePair2_3: %v", err) 242 } 243 if parser.st != psPackage2_3 { 244 t.Errorf("parser is in state %v, expected %v", parser.st, psPackage2_3) 245 } 246} 247 248// ===== Package data section tests ===== 249func TestParser2_3CanParsePackageTags(t *testing.T) { 250 parser := tvParser2_3{ 251 doc: &v2_3.Document{Packages: []*v2_3.Package{}}, 252 st: psPackage2_3, 253 pkg: &v2_3.Package{}, 254 } 255 256 // should not yet be in Packages map, b/c no SPDX identifier 257 if len(parser.doc.Packages) != 0 { 258 t.Errorf("expected 0 packages, got %d", len(parser.doc.Packages)) 259 } 260 261 // Package Name 262 err := parser.parsePairFromPackage2_3("PackageName", "p1") 263 if err != nil { 264 t.Errorf("expected nil error, got %v", err) 265 } 266 if parser.pkg.PackageName != "p1" { 267 t.Errorf("got %v for PackageName", parser.pkg.PackageName) 268 } 269 // still should not yet be in Packages map, b/c no SPDX identifier 270 if len(parser.doc.Packages) != 0 { 271 t.Errorf("expected 0 packages, got %d", len(parser.doc.Packages)) 272 } 273 274 // Package SPDX Identifier 275 err = parser.parsePairFromPackage2_3("SPDXID", "SPDXRef-p1") 276 if err != nil { 277 t.Errorf("expected nil error, got %v", err) 278 } 279 // "SPDXRef-" prefix should be removed from the item 280 if parser.pkg.PackageSPDXIdentifier != "p1" { 281 t.Errorf("got %v for PackageSPDXIdentifier", parser.pkg.PackageSPDXIdentifier) 282 } 283 // and it should now be added to the Packages map 284 if len(parser.doc.Packages) != 1 { 285 t.Errorf("expected 1 package, got %d", len(parser.doc.Packages)) 286 } 287 if parser.doc.Packages[0] != parser.pkg { 288 t.Errorf("expected to point to parser.pkg, got %v", parser.doc.Packages[0]) 289 } 290 291 // Package Version 292 err = parser.parsePairFromPackage2_3("PackageVersion", "2.1.1") 293 if err != nil { 294 t.Errorf("expected nil error, got %v", err) 295 } 296 if parser.pkg.PackageVersion != "2.1.1" { 297 t.Errorf("got %v for PackageVersion", parser.pkg.PackageVersion) 298 } 299 300 // Package File Name 301 err = parser.parsePairFromPackage2_3("PackageFileName", "p1-2.1.1.tar.gz") 302 if err != nil { 303 t.Errorf("expected nil error, got %v", err) 304 } 305 if parser.pkg.PackageFileName != "p1-2.1.1.tar.gz" { 306 t.Errorf("got %v for PackageFileName", parser.pkg.PackageFileName) 307 } 308 309 // Package Supplier 310 // SKIP -- separate tests for subvalues below 311 312 // Package Originator 313 // SKIP -- separate tests for subvalues below 314 315 // Package Download Location 316 err = parser.parsePairFromPackage2_3("PackageDownloadLocation", "https://example.com/whatever") 317 if err != nil { 318 t.Errorf("expected nil error, got %v", err) 319 } 320 if parser.pkg.PackageDownloadLocation != "https://example.com/whatever" { 321 t.Errorf("got %v for PackageDownloadLocation", parser.pkg.PackageDownloadLocation) 322 } 323 324 // Files Analyzed 325 err = parser.parsePairFromPackage2_3("FilesAnalyzed", "false") 326 if err != nil { 327 t.Errorf("expected nil error, got %v", err) 328 } 329 if parser.pkg.FilesAnalyzed != false { 330 t.Errorf("got %v for FilesAnalyzed", parser.pkg.FilesAnalyzed) 331 } 332 if parser.pkg.IsFilesAnalyzedTagPresent != true { 333 t.Errorf("got %v for IsFilesAnalyzedTagPresent", parser.pkg.IsFilesAnalyzedTagPresent) 334 } 335 336 // Package Verification Code 337 // SKIP -- separate tests for "excludes", or not, below 338 339 testChecksums := map[common.ChecksumAlgorithm]string{ 340 "MD5": "624c1abb3664f4b35547e7c73864ad24", 341 "SHA1": "85ed0817af83a24ad8da68c2b5094de69833983c", 342 "SHA256": "11b6d3ee554eedf79299905a98f9b9a04e498210b59f15094c916c91d150efcd", 343 "SHA512": "4ced3267f5ed38df65ceebc43e97aa6c2948cc7ef3288c2e5074e7df7fab544cc93339604513ea5f65616f9ed1c48581465043c8a9b693ef20fd4fddaf25e1b9", 344 "BLAKE3": "981d32ed7aad9e408c5c36f6346c915ba11c2bd8b3e7d44902a11d7a141abdd9", 345 } 346 347 for algo, tc := range testChecksums { 348 if err := parser.parsePairFromPackage2_3( 349 "PackageChecksum", fmt.Sprintf("%s: %s", algo, tc)); err != nil { 350 t.Errorf("expected error, got %v", err) 351 } 352 } 353 354 for _, checksum := range parser.pkg.PackageChecksums { 355 if checksum.Value != testChecksums[checksum.Algorithm] { 356 t.Errorf( 357 "expected %s for PackageChecksum%s, got %s", 358 testChecksums[checksum.Algorithm], checksum.Algorithm, checksum.Value, 359 ) 360 } 361 } 362 363 // Package Home Page 364 err = parser.parsePairFromPackage2_3("PackageHomePage", "https://example.com/whatever2") 365 if err != nil { 366 t.Errorf("expected nil error, got %v", err) 367 } 368 if parser.pkg.PackageHomePage != "https://example.com/whatever2" { 369 t.Errorf("got %v for PackageHomePage", parser.pkg.PackageHomePage) 370 } 371 372 // Package Source Info 373 err = parser.parsePairFromPackage2_3("PackageSourceInfo", "random comment") 374 if err != nil { 375 t.Errorf("expected nil error, got %v", err) 376 } 377 if parser.pkg.PackageSourceInfo != "random comment" { 378 t.Errorf("got %v for PackageSourceInfo", parser.pkg.PackageSourceInfo) 379 } 380 381 // Package License Concluded 382 err = parser.parsePairFromPackage2_3("PackageLicenseConcluded", "Apache-2.0 OR GPL-2.0-or-later") 383 if err != nil { 384 t.Errorf("expected nil error, got %v", err) 385 } 386 if parser.pkg.PackageLicenseConcluded != "Apache-2.0 OR GPL-2.0-or-later" { 387 t.Errorf("got %v for PackageLicenseConcluded", parser.pkg.PackageLicenseConcluded) 388 } 389 390 // All Licenses Info From Files 391 lics := []string{ 392 "Apache-2.0", 393 "GPL-2.0-or-later", 394 "CC0-1.0", 395 } 396 for _, lic := range lics { 397 err = parser.parsePairFromPackage2_3("PackageLicenseInfoFromFiles", lic) 398 if err != nil { 399 t.Errorf("expected nil error, got %v", err) 400 } 401 } 402 for _, licWant := range lics { 403 flagFound := false 404 for _, licCheck := range parser.pkg.PackageLicenseInfoFromFiles { 405 if licWant == licCheck { 406 flagFound = true 407 } 408 } 409 if flagFound == false { 410 t.Errorf("didn't find %s in PackageLicenseInfoFromFiles", licWant) 411 } 412 } 413 if len(lics) != len(parser.pkg.PackageLicenseInfoFromFiles) { 414 t.Errorf("expected %d licenses in PackageLicenseInfoFromFiles, got %d", len(lics), 415 len(parser.pkg.PackageLicenseInfoFromFiles)) 416 } 417 418 // Package License Declared 419 err = parser.parsePairFromPackage2_3("PackageLicenseDeclared", "Apache-2.0 OR GPL-2.0-or-later") 420 if err != nil { 421 t.Errorf("expected nil error, got %v", err) 422 } 423 if parser.pkg.PackageLicenseDeclared != "Apache-2.0 OR GPL-2.0-or-later" { 424 t.Errorf("got %v for PackageLicenseDeclared", parser.pkg.PackageLicenseDeclared) 425 } 426 427 // Package License Comments 428 err = parser.parsePairFromPackage2_3("PackageLicenseComments", "this is a license comment") 429 if err != nil { 430 t.Errorf("expected nil error, got %v", err) 431 } 432 if parser.pkg.PackageLicenseComments != "this is a license comment" { 433 t.Errorf("got %v for PackageLicenseComments", parser.pkg.PackageLicenseComments) 434 } 435 436 // Package Copyright Text 437 err = parser.parsePairFromPackage2_3("PackageCopyrightText", "Copyright (c) me myself and i") 438 if err != nil { 439 t.Errorf("expected nil error, got %v", err) 440 } 441 if parser.pkg.PackageCopyrightText != "Copyright (c) me myself and i" { 442 t.Errorf("got %v for PackageCopyrightText", parser.pkg.PackageCopyrightText) 443 } 444 445 // Package Summary 446 err = parser.parsePairFromPackage2_3("PackageSummary", "i wrote this package") 447 if err != nil { 448 t.Errorf("expected nil error, got %v", err) 449 } 450 if parser.pkg.PackageSummary != "i wrote this package" { 451 t.Errorf("got %v for PackageSummary", parser.pkg.PackageSummary) 452 } 453 454 // Package Description 455 err = parser.parsePairFromPackage2_3("PackageDescription", "i wrote this package a lot") 456 if err != nil { 457 t.Errorf("expected nil error, got %v", err) 458 } 459 if parser.pkg.PackageDescription != "i wrote this package a lot" { 460 t.Errorf("got %v for PackageDescription", parser.pkg.PackageDescription) 461 } 462 463 // Package Comment 464 err = parser.parsePairFromPackage2_3("PackageComment", "i scanned this package") 465 if err != nil { 466 t.Errorf("expected nil error, got %v", err) 467 } 468 if parser.pkg.PackageComment != "i scanned this package" { 469 t.Errorf("got %v for PackageComment", parser.pkg.PackageComment) 470 } 471 472 // Package Attribution Text 473 attrs := []string{ 474 "Include this notice in all advertising materials", 475 "This is a \nmulti-line string", 476 } 477 for _, attr := range attrs { 478 err = parser.parsePairFromPackage2_3("PackageAttributionText", attr) 479 if err != nil { 480 t.Errorf("expected nil error, got %v", err) 481 } 482 } 483 for _, attrWant := range attrs { 484 flagFound := false 485 for _, attrCheck := range parser.pkg.PackageAttributionTexts { 486 if attrWant == attrCheck { 487 flagFound = true 488 } 489 } 490 if flagFound == false { 491 t.Errorf("didn't find %s in PackageAttributionText", attrWant) 492 } 493 } 494 if len(attrs) != len(parser.pkg.PackageAttributionTexts) { 495 t.Errorf("expected %d attribution texts in PackageAttributionTexts, got %d", len(attrs), 496 len(parser.pkg.PackageAttributionTexts)) 497 } 498 499 // Package External References and Comments 500 ref1 := "SECURITY cpe23Type cpe:2.3:a:pivotal_software:spring_framework:4.1.0:*:*:*:*:*:*:*" 501 ref1Category := "SECURITY" 502 ref1Type := "cpe23Type" 503 ref1Locator := "cpe:2.3:a:pivotal_software:spring_framework:4.1.0:*:*:*:*:*:*:*" 504 ref1Comment := "this is comment #1" 505 ref2 := "OTHER LocationRef-acmeforge acmecorp/acmenator/4.1.3alpha" 506 ref2Category := "OTHER" 507 ref2Type := "LocationRef-acmeforge" 508 ref2Locator := "acmecorp/acmenator/4.1.3alpha" 509 ref2Comment := "this is comment #2" 510 err = parser.parsePairFromPackage2_3("ExternalRef", ref1) 511 if err != nil { 512 t.Errorf("expected nil error, got %v", err) 513 } 514 if len(parser.pkg.PackageExternalReferences) != 1 { 515 t.Errorf("expected 1 external reference, got %d", len(parser.pkg.PackageExternalReferences)) 516 } 517 if parser.pkgExtRef == nil { 518 t.Errorf("expected non-nil pkgExtRef, got nil") 519 } 520 if parser.pkg.PackageExternalReferences[0] == nil { 521 t.Errorf("expected non-nil PackageExternalReferences[0], got nil") 522 } 523 if parser.pkgExtRef != parser.pkg.PackageExternalReferences[0] { 524 t.Errorf("expected pkgExtRef to match PackageExternalReferences[0], got no match") 525 } 526 err = parser.parsePairFromPackage2_3("ExternalRefComment", ref1Comment) 527 if err != nil { 528 t.Errorf("expected nil error, got %v", err) 529 } 530 err = parser.parsePairFromPackage2_3("ExternalRef", ref2) 531 if err != nil { 532 t.Errorf("expected nil error, got %v", err) 533 } 534 if len(parser.pkg.PackageExternalReferences) != 2 { 535 t.Errorf("expected 2 external references, got %d", len(parser.pkg.PackageExternalReferences)) 536 } 537 if parser.pkgExtRef == nil { 538 t.Errorf("expected non-nil pkgExtRef, got nil") 539 } 540 if parser.pkg.PackageExternalReferences[1] == nil { 541 t.Errorf("expected non-nil PackageExternalReferences[1], got nil") 542 } 543 if parser.pkgExtRef != parser.pkg.PackageExternalReferences[1] { 544 t.Errorf("expected pkgExtRef to match PackageExternalReferences[1], got no match") 545 } 546 err = parser.parsePairFromPackage2_3("ExternalRefComment", ref2Comment) 547 if err != nil { 548 t.Errorf("expected nil error, got %v", err) 549 } 550 // finally, check these values 551 gotRef1 := parser.pkg.PackageExternalReferences[0] 552 if gotRef1.Category != ref1Category { 553 t.Errorf("expected ref1 category to be %s, got %s", gotRef1.Category, ref1Category) 554 } 555 if gotRef1.RefType != ref1Type { 556 t.Errorf("expected ref1 type to be %s, got %s", gotRef1.RefType, ref1Type) 557 } 558 if gotRef1.Locator != ref1Locator { 559 t.Errorf("expected ref1 locator to be %s, got %s", gotRef1.Locator, ref1Locator) 560 } 561 if gotRef1.ExternalRefComment != ref1Comment { 562 t.Errorf("expected ref1 comment to be %s, got %s", gotRef1.ExternalRefComment, ref1Comment) 563 } 564 gotRef2 := parser.pkg.PackageExternalReferences[1] 565 if gotRef2.Category != ref2Category { 566 t.Errorf("expected ref2 category to be %s, got %s", gotRef2.Category, ref2Category) 567 } 568 if gotRef2.RefType != ref2Type { 569 t.Errorf("expected ref2 type to be %s, got %s", gotRef2.RefType, ref2Type) 570 } 571 if gotRef2.Locator != ref2Locator { 572 t.Errorf("expected ref2 locator to be %s, got %s", gotRef2.Locator, ref2Locator) 573 } 574 if gotRef2.ExternalRefComment != ref2Comment { 575 t.Errorf("expected ref2 comment to be %s, got %s", gotRef2.ExternalRefComment, ref2Comment) 576 } 577 578} 579 580func TestParser2_3CanParsePackageSupplierPersonTag(t *testing.T) { 581 parser := tvParser2_3{ 582 doc: &v2_3.Document{Packages: []*v2_3.Package{}}, 583 st: psPackage2_3, 584 pkg: &v2_3.Package{PackageName: "p1", PackageSPDXIdentifier: "p1"}, 585 } 586 parser.doc.Packages = append(parser.doc.Packages, parser.pkg) 587 588 // Package Supplier: Person 589 err := parser.parsePairFromPackage2_3("PackageSupplier", "Person: John Doe") 590 if err != nil { 591 t.Errorf("expected nil error, got %v", err) 592 } 593 if parser.pkg.PackageSupplier.Supplier != "John Doe" { 594 t.Errorf("got %v for PackageSupplierPerson", parser.pkg.PackageSupplier.Supplier) 595 } 596} 597 598func TestParser2_3CanParsePackageSupplierOrganizationTag(t *testing.T) { 599 parser := tvParser2_3{ 600 doc: &v2_3.Document{Packages: []*v2_3.Package{}}, 601 st: psPackage2_3, 602 pkg: &v2_3.Package{PackageName: "p1", PackageSPDXIdentifier: "p1"}, 603 } 604 parser.doc.Packages = append(parser.doc.Packages, parser.pkg) 605 606 // Package Supplier: Organization 607 err := parser.parsePairFromPackage2_3("PackageSupplier", "Organization: John Doe, Inc.") 608 if err != nil { 609 t.Errorf("expected nil error, got %v", err) 610 } 611 if parser.pkg.PackageSupplier.Supplier != "John Doe, Inc." { 612 t.Errorf("got %v for PackageSupplierOrganization", parser.pkg.PackageSupplier.Supplier) 613 } 614} 615 616func TestParser2_3CanParsePackageSupplierNOASSERTIONTag(t *testing.T) { 617 parser := tvParser2_3{ 618 doc: &v2_3.Document{Packages: []*v2_3.Package{}}, 619 st: psPackage2_3, 620 pkg: &v2_3.Package{PackageName: "p1", PackageSPDXIdentifier: "p1"}, 621 } 622 parser.doc.Packages = append(parser.doc.Packages, parser.pkg) 623 624 // Package Supplier: NOASSERTION 625 err := parser.parsePairFromPackage2_3("PackageSupplier", "NOASSERTION") 626 if err != nil { 627 t.Errorf("expected nil error, got %v", err) 628 } 629 if parser.pkg.PackageSupplier.Supplier != "NOASSERTION" { 630 t.Errorf("got value for Supplier, expected NOASSERTION") 631 } 632} 633 634func TestParser2_3CanParsePackageOriginatorPersonTag(t *testing.T) { 635 parser := tvParser2_3{ 636 doc: &v2_3.Document{Packages: []*v2_3.Package{}}, 637 st: psPackage2_3, 638 pkg: &v2_3.Package{PackageName: "p1", PackageSPDXIdentifier: "p1"}, 639 } 640 parser.doc.Packages = append(parser.doc.Packages, parser.pkg) 641 642 // Package Originator: Person 643 err := parser.parsePairFromPackage2_3("PackageOriginator", "Person: John Doe") 644 if err != nil { 645 t.Errorf("expected nil error, got %v", err) 646 } 647 if parser.pkg.PackageOriginator.Originator != "John Doe" { 648 t.Errorf("got %v for PackageOriginator", parser.pkg.PackageOriginator.Originator) 649 } 650} 651 652func TestParser2_3CanParsePackageOriginatorOrganizationTag(t *testing.T) { 653 parser := tvParser2_3{ 654 doc: &v2_3.Document{Packages: []*v2_3.Package{}}, 655 st: psPackage2_3, 656 pkg: &v2_3.Package{PackageName: "p1", PackageSPDXIdentifier: "p1"}, 657 } 658 parser.doc.Packages = append(parser.doc.Packages, parser.pkg) 659 660 // Package Originator: Organization 661 err := parser.parsePairFromPackage2_3("PackageOriginator", "Organization: John Doe, Inc.") 662 if err != nil { 663 t.Errorf("expected nil error, got %v", err) 664 } 665 if parser.pkg.PackageOriginator.Originator != "John Doe, Inc." { 666 t.Errorf("got %v for PackageOriginator", parser.pkg.PackageOriginator.Originator) 667 } 668} 669 670func TestParser2_3CanParsePackageOriginatorNOASSERTIONTag(t *testing.T) { 671 parser := tvParser2_3{ 672 doc: &v2_3.Document{Packages: []*v2_3.Package{}}, 673 st: psPackage2_3, 674 pkg: &v2_3.Package{PackageName: "p1", PackageSPDXIdentifier: "p1"}, 675 } 676 parser.doc.Packages = append(parser.doc.Packages, parser.pkg) 677 678 // Package Originator: NOASSERTION 679 err := parser.parsePairFromPackage2_3("PackageOriginator", "NOASSERTION") 680 if err != nil { 681 t.Errorf("expected nil error, got %v", err) 682 } 683 if parser.pkg.PackageOriginator.Originator != "NOASSERTION" { 684 t.Errorf("got false for PackageOriginatorNOASSERTION") 685 } 686} 687 688func TestParser2_3CanParsePackageVerificationCodeTagWithExcludes(t *testing.T) { 689 parser := tvParser2_3{ 690 doc: &v2_3.Document{Packages: []*v2_3.Package{}}, 691 st: psPackage2_3, 692 pkg: &v2_3.Package{PackageName: "p1", PackageSPDXIdentifier: "p1"}, 693 } 694 parser.doc.Packages = append(parser.doc.Packages, parser.pkg) 695 696 // Package Verification Code with excludes parenthetical 697 code := "d6a770ba38583ed4bb4525bd96e50461655d2758" 698 fileName := "./package.spdx" 699 fullCodeValue := "d6a770ba38583ed4bb4525bd96e50461655d2758 (excludes: ./package.spdx)" 700 err := parser.parsePairFromPackage2_3("PackageVerificationCode", fullCodeValue) 701 if err != nil { 702 t.Errorf("expected nil error, got %v", err) 703 } 704 if parser.pkg.PackageVerificationCode.Value != code { 705 t.Errorf("got %v for PackageVerificationCode", parser.pkg.PackageVerificationCode) 706 } 707 if len(parser.pkg.PackageVerificationCode.ExcludedFiles) != 1 || parser.pkg.PackageVerificationCode.ExcludedFiles[0] != fileName { 708 t.Errorf("got %v for PackageVerificationCodeExcludedFile", parser.pkg.PackageVerificationCode.ExcludedFiles) 709 } 710 711} 712 713func TestParser2_3CanParsePackageVerificationCodeTagWithoutExcludes(t *testing.T) { 714 parser := tvParser2_3{ 715 doc: &v2_3.Document{Packages: []*v2_3.Package{}}, 716 st: psPackage2_3, 717 pkg: &v2_3.Package{PackageName: "p1", PackageSPDXIdentifier: "p1"}, 718 } 719 parser.doc.Packages = append(parser.doc.Packages, parser.pkg) 720 721 // Package Verification Code without excludes parenthetical 722 code := "d6a770ba38583ed4bb4525bd96e50461655d2758" 723 err := parser.parsePairFromPackage2_3("PackageVerificationCode", code) 724 if err != nil { 725 t.Errorf("expected nil error, got %v", err) 726 } 727 if parser.pkg.PackageVerificationCode.Value != code { 728 t.Errorf("got %v for PackageVerificationCode", parser.pkg.PackageVerificationCode) 729 } 730 if len(parser.pkg.PackageVerificationCode.ExcludedFiles) != 0 { 731 t.Errorf("got %v for PackageVerificationCodeExcludedFile", parser.pkg.PackageVerificationCode.ExcludedFiles) 732 } 733 734} 735 736func TestParser2_3PackageExternalRefPointerChangesAfterTags(t *testing.T) { 737 parser := tvParser2_3{ 738 doc: &v2_3.Document{Packages: []*v2_3.Package{}}, 739 st: psPackage2_3, 740 pkg: &v2_3.Package{PackageName: "p1", PackageSPDXIdentifier: "p1"}, 741 } 742 parser.doc.Packages = append(parser.doc.Packages, parser.pkg) 743 744 ref1 := "SECURITY cpe23Type cpe:2.3:a:pivotal_software:spring_framework:4.1.0:*:*:*:*:*:*:*" 745 err := parser.parsePairFromPackage2_3("ExternalRef", ref1) 746 if err != nil { 747 t.Errorf("expected nil error, got %v", err) 748 } 749 if parser.pkgExtRef == nil { 750 t.Errorf("expected non-nil external reference pointer, got nil") 751 } 752 753 // now, a comment; pointer should go away 754 err = parser.parsePairFromPackage2_3("ExternalRefComment", "whatever") 755 if err != nil { 756 t.Errorf("expected nil error, got %v", err) 757 } 758 if parser.pkgExtRef != nil { 759 t.Errorf("expected nil external reference pointer, got non-nil") 760 } 761 762 ref2 := "Other LocationRef-something https://example.com/whatever" 763 err = parser.parsePairFromPackage2_3("ExternalRef", ref2) 764 if err != nil { 765 t.Errorf("expected nil error, got %v", err) 766 } 767 if parser.pkgExtRef == nil { 768 t.Errorf("expected non-nil external reference pointer, got nil") 769 } 770 771 // and some other random tag makes the pointer go away too 772 err = parser.parsePairFromPackage2_3("PackageSummary", "whatever") 773 if err != nil { 774 t.Errorf("expected nil error, got %v", err) 775 } 776 if parser.pkgExtRef != nil { 777 t.Errorf("expected nil external reference pointer, got non-nil") 778 } 779} 780 781func TestParser2_3PackageCreatesRelationshipInDocument(t *testing.T) { 782 parser := tvParser2_3{ 783 doc: &v2_3.Document{Packages: []*v2_3.Package{}}, 784 st: psPackage2_3, 785 pkg: &v2_3.Package{PackageName: "p1", PackageSPDXIdentifier: "p1"}, 786 } 787 parser.doc.Packages = append(parser.doc.Packages, parser.pkg) 788 789 err := parser.parsePair2_3("Relationship", "SPDXRef-blah CONTAINS SPDXRef-blah-whatever") 790 if err != nil { 791 t.Errorf("got error when calling parsePair2_3: %v", err) 792 } 793 if parser.rln == nil { 794 t.Fatalf("parser didn't create and point to Relationship struct") 795 } 796 if parser.rln != parser.doc.Relationships[0] { 797 t.Errorf("pointer to new Relationship doesn't match idx 0 for doc.Relationships[]") 798 } 799} 800 801func TestParser2_3PackageCreatesAnnotationInDocument(t *testing.T) { 802 parser := tvParser2_3{ 803 doc: &v2_3.Document{Packages: []*v2_3.Package{}}, 804 st: psPackage2_3, 805 pkg: &v2_3.Package{PackageName: "p1", PackageSPDXIdentifier: "p1"}, 806 } 807 parser.doc.Packages = append(parser.doc.Packages, parser.pkg) 808 809 err := parser.parsePair2_3("Annotator", "Person: John Doe ()") 810 if err != nil { 811 t.Errorf("got error when calling parsePair2_3: %v", err) 812 } 813 if parser.ann == nil { 814 t.Fatalf("parser didn't create and point to Annotation struct") 815 } 816 if parser.ann != parser.doc.Annotations[0] { 817 t.Errorf("pointer to new Annotation doesn't match idx 0 for doc.Annotations[]") 818 } 819} 820 821func TestParser2_3PackageUnknownTagFails(t *testing.T) { 822 parser := tvParser2_3{ 823 doc: &v2_3.Document{Packages: []*v2_3.Package{}}, 824 st: psPackage2_3, 825 pkg: &v2_3.Package{PackageName: "p1", PackageSPDXIdentifier: "p1"}, 826 } 827 parser.doc.Packages = append(parser.doc.Packages, parser.pkg) 828 829 err := parser.parsePairFromPackage2_3("blah", "something") 830 if err == nil { 831 t.Errorf("expected error from parsing unknown tag") 832 } 833} 834 835func TestParser2_3FailsIfInvalidSPDXIDInPackageSection(t *testing.T) { 836 parser := tvParser2_3{ 837 doc: &v2_3.Document{Packages: []*v2_3.Package{}}, 838 st: psPackage2_3, 839 pkg: &v2_3.Package{}, 840 } 841 842 // start with Package Name 843 err := parser.parsePairFromPackage2_3("PackageName", "p1") 844 if err != nil { 845 t.Errorf("expected nil error, got %v", err) 846 } 847 // invalid ID format 848 err = parser.parsePairFromPackage2_3("SPDXID", "whoops") 849 if err == nil { 850 t.Errorf("expected non-nil error, got nil") 851 } 852} 853 854func TestParser2_3FailsIfInvalidPackageSupplierFormat(t *testing.T) { 855 parser := tvParser2_3{ 856 doc: &v2_3.Document{Packages: []*v2_3.Package{}}, 857 st: psPackage2_3, 858 pkg: &v2_3.Package{}, 859 } 860 861 // start with Package Name 862 err := parser.parsePairFromPackage2_3("PackageName", "p1") 863 if err != nil { 864 t.Errorf("expected nil error, got %v", err) 865 } 866 // invalid supplier format 867 err = parser.parsePairFromPackage2_3("PackageSupplier", "whoops") 868 if err == nil { 869 t.Errorf("expected non-nil error, got nil") 870 } 871} 872 873func TestParser2_3FailsIfUnknownPackageSupplierType(t *testing.T) { 874 parser := tvParser2_3{ 875 doc: &v2_3.Document{Packages: []*v2_3.Package{}}, 876 st: psPackage2_3, 877 pkg: &v2_3.Package{}, 878 } 879 880 // start with Package Name 881 err := parser.parsePairFromPackage2_3("PackageName", "p1") 882 if err != nil { 883 t.Errorf("expected nil error, got %v", err) 884 } 885 // invalid supplier type 886 err = parser.parsePairFromPackage2_3("PackageSupplier", "whoops: John Doe") 887 if err == nil { 888 t.Errorf("expected non-nil error, got nil") 889 } 890} 891 892func TestParser2_3FailsIfInvalidPackageOriginatorFormat(t *testing.T) { 893 parser := tvParser2_3{ 894 doc: &v2_3.Document{Packages: []*v2_3.Package{}}, 895 st: psPackage2_3, 896 pkg: &v2_3.Package{}, 897 } 898 899 // start with Package Name 900 err := parser.parsePairFromPackage2_3("PackageName", "p1") 901 if err != nil { 902 t.Errorf("expected nil error, got %v", err) 903 } 904 // invalid originator format 905 err = parser.parsePairFromPackage2_3("PackageOriginator", "whoops") 906 if err == nil { 907 t.Errorf("expected non-nil error, got nil") 908 } 909} 910 911func TestParser2_3FailsIfUnknownPackageOriginatorType(t *testing.T) { 912 parser := tvParser2_3{ 913 doc: &v2_3.Document{Packages: []*v2_3.Package{}}, 914 st: psPackage2_3, 915 pkg: &v2_3.Package{}, 916 } 917 918 // start with Package Name 919 err := parser.parsePairFromPackage2_3("PackageName", "p1") 920 if err != nil { 921 t.Errorf("expected nil error, got %v", err) 922 } 923 // invalid originator type 924 err = parser.parsePairFromPackage2_3("PackageOriginator", "whoops: John Doe") 925 if err == nil { 926 t.Errorf("expected non-nil error, got nil") 927 } 928} 929 930func TestParser2_3SetsFilesAnalyzedTagsCorrectly(t *testing.T) { 931 parser := tvParser2_3{ 932 doc: &v2_3.Document{Packages: []*v2_3.Package{}}, 933 st: psPackage2_3, 934 pkg: &v2_3.Package{}, 935 } 936 937 // start with Package Name 938 err := parser.parsePairFromPackage2_3("PackageName", "p1") 939 if err != nil { 940 t.Errorf("expected nil error, got %v", err) 941 } 942 // set tag 943 err = parser.parsePairFromPackage2_3("FilesAnalyzed", "true") 944 if err != nil { 945 t.Errorf("expected nil error, got %v", err) 946 } 947 if parser.pkg.FilesAnalyzed != true { 948 t.Errorf("expected %v, got %v", true, parser.pkg.FilesAnalyzed) 949 } 950 if parser.pkg.IsFilesAnalyzedTagPresent != true { 951 t.Errorf("expected %v, got %v", true, parser.pkg.IsFilesAnalyzedTagPresent) 952 } 953} 954 955func TestParser2_3FailsIfInvalidPackageChecksumFormat(t *testing.T) { 956 parser := tvParser2_3{ 957 doc: &v2_3.Document{Packages: []*v2_3.Package{}}, 958 st: psPackage2_3, 959 pkg: &v2_3.Package{}, 960 } 961 962 // start with Package Name 963 err := parser.parsePairFromPackage2_3("PackageName", "p1") 964 if err != nil { 965 t.Errorf("expected nil error, got %v", err) 966 } 967 // invalid checksum format 968 err = parser.parsePairFromPackage2_3("PackageChecksum", "whoops") 969 if err == nil { 970 t.Errorf("expected non-nil error, got nil") 971 } 972} 973 974func TestParser2_3FailsIfInvalidPackageChecksumType(t *testing.T) { 975 parser := tvParser2_3{ 976 doc: &v2_3.Document{Packages: []*v2_3.Package{}}, 977 st: psPackage2_3, 978 pkg: &v2_3.Package{}, 979 } 980 981 // start with Package Name 982 err := parser.parsePairFromPackage2_3("PackageName", "p1") 983 if err != nil { 984 t.Errorf("expected nil error, got %v", err) 985 } 986 // invalid checksum type 987 err = parser.parsePairFromPackage2_3("PackageChecksum", "whoops: blah") 988 if err == nil { 989 t.Errorf("expected non-nil error, got nil") 990 } 991} 992 993func TestParser2_3FailsIfInvalidExternalRefFormat(t *testing.T) { 994 parser := tvParser2_3{ 995 doc: &v2_3.Document{Packages: []*v2_3.Package{}}, 996 st: psPackage2_3, 997 pkg: &v2_3.Package{}, 998 } 999 1000 // start with Package Name 1001 err := parser.parsePairFromPackage2_3("PackageName", "p1") 1002 if err != nil { 1003 t.Errorf("expected nil error, got %v", err) 1004 } 1005 // invalid external ref format 1006 err = parser.parsePairFromPackage2_3("ExternalRef", "whoops") 1007 if err == nil { 1008 t.Errorf("expected non-nil error, got nil") 1009 } 1010} 1011 1012func TestParser2_3FailsIfExternalRefCommentBeforeExternalRef(t *testing.T) { 1013 parser := tvParser2_3{ 1014 doc: &v2_3.Document{Packages: []*v2_3.Package{}}, 1015 st: psPackage2_3, 1016 pkg: &v2_3.Package{}, 1017 } 1018 1019 // start with Package Name 1020 err := parser.parsePairFromPackage2_3("PackageName", "p1") 1021 if err != nil { 1022 t.Errorf("expected nil error, got %v", err) 1023 } 1024 // external ref comment before external ref 1025 err = parser.parsePairFromPackage2_3("ExternalRefComment", "whoops") 1026 if err == nil { 1027 t.Errorf("expected non-nil error, got nil") 1028 } 1029} 1030 1031// ===== Helper function tests ===== 1032 1033func TestCanCheckAndExtractExcludesFilenameAndCode(t *testing.T) { 1034 code := "d6a770ba38583ed4bb4525bd96e50461655d2758" 1035 fileName := "./package.spdx" 1036 fullCodeValue := "d6a770ba38583ed4bb4525bd96e50461655d2758 (excludes: ./package.spdx)" 1037 1038 gotCode := extractCodeAndExcludes(fullCodeValue) 1039 if gotCode.Value != code { 1040 t.Errorf("got %v for gotCode", gotCode) 1041 } 1042 if len(gotCode.ExcludedFiles) != 1 || gotCode.ExcludedFiles[0] != fileName { 1043 t.Errorf("got %v for gotFileName", gotCode.ExcludedFiles) 1044 } 1045} 1046 1047func TestCanExtractPackageExternalReference(t *testing.T) { 1048 ref1 := "SECURITY cpe23Type cpe:2.3:a:pivotal_software:spring_framework:4.1.0:*:*:*:*:*:*:*" 1049 category := "SECURITY" 1050 refType := "cpe23Type" 1051 location := "cpe:2.3:a:pivotal_software:spring_framework:4.1.0:*:*:*:*:*:*:*" 1052 1053 gotCategory, gotRefType, gotLocation, err := extractPackageExternalReference(ref1) 1054 if err != nil { 1055 t.Errorf("got non-nil error: %v", err) 1056 } 1057 if gotCategory != category { 1058 t.Errorf("expected category %s, got %s", category, gotCategory) 1059 } 1060 if gotRefType != refType { 1061 t.Errorf("expected refType %s, got %s", refType, gotRefType) 1062 } 1063 if gotLocation != location { 1064 t.Errorf("expected location %s, got %s", location, gotLocation) 1065 } 1066} 1067 1068func TestCanExtractPackageExternalReferenceWithExtraWhitespace(t *testing.T) { 1069 ref1 := " SECURITY \t cpe23Type cpe:2.3:a:pivotal_software:spring_framework:4.1.0:*:*:*:*:*:*:* \t " 1070 category := "SECURITY" 1071 refType := "cpe23Type" 1072 location := "cpe:2.3:a:pivotal_software:spring_framework:4.1.0:*:*:*:*:*:*:*" 1073 1074 gotCategory, gotRefType, gotLocation, err := extractPackageExternalReference(ref1) 1075 if err != nil { 1076 t.Errorf("got non-nil error: %v", err) 1077 } 1078 if gotCategory != category { 1079 t.Errorf("expected category %s, got %s", category, gotCategory) 1080 } 1081 if gotRefType != refType { 1082 t.Errorf("expected refType %s, got %s", refType, gotRefType) 1083 } 1084 if gotLocation != location { 1085 t.Errorf("expected location %s, got %s", location, gotLocation) 1086 } 1087} 1088 1089func TestFailsPackageExternalRefWithInvalidFormat(t *testing.T) { 1090 _, _, _, err := extractPackageExternalReference("whoops") 1091 if err == nil { 1092 t.Errorf("expected non-nil error, got nil") 1093 } 1094} 1095 1096func TestParser2_3PackageWithoutSpdxIdentifierThrowsError(t *testing.T) { 1097 // More than one package, the previous package doesn't contain an SPDX ID 1098 pkgOldName := "p1" 1099 parser := tvParser2_3{ 1100 doc: &v2_3.Document{Packages: []*v2_3.Package{}}, 1101 st: psPackage2_3, 1102 pkg: &v2_3.Package{PackageName: pkgOldName}, 1103 } 1104 pkgOld := parser.pkg 1105 parser.doc.Packages = append(parser.doc.Packages, pkgOld) 1106 // the Document's Packages should have this one only 1107 if parser.doc.Packages[0] != pkgOld { 1108 t.Errorf("expected package %v, got %v", pkgOld, parser.doc.Packages[0]) 1109 } 1110 if len(parser.doc.Packages) != 1 { 1111 t.Errorf("expected 1 package, got %d", len(parser.doc.Packages)) 1112 } 1113 1114 pkgName := "p2" 1115 err := parser.parsePair2_3("PackageName", pkgName) 1116 if err == nil { 1117 t.Errorf("package without SPDX Identifier getting accepted") 1118 } 1119} 1120