1// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later 2 3package parser2v3 4 5import ( 6 "fmt" 7 8 "github.com/spdx/tools-golang/spdx/common" 9 "github.com/spdx/tools-golang/spdx/v2_3" 10) 11 12func (parser *tvParser2_3) parsePairFromFile2_3(tag string, value string) error { 13 // expire fileAOP for anything other than an AOPHomePage or AOPURI 14 // (we'll actually handle the HomePage and URI further below) 15 if tag != "ArtifactOfProjectHomePage" && tag != "ArtifactOfProjectURI" { 16 parser.fileAOP = nil 17 } 18 19 switch tag { 20 // tag for creating new file section 21 case "FileName": 22 // check if the previous file contained an spdx Id or not 23 if parser.file != nil && parser.file.FileSPDXIdentifier == nullSpdxElementId2_3 { 24 return fmt.Errorf("file with FileName %s does not have SPDX identifier", parser.file.FileName) 25 } 26 parser.file = &v2_3.File{} 27 parser.file.FileName = value 28 // tag for creating new package section and going back to parsing Package 29 case "PackageName": 30 parser.st = psPackage2_3 31 // check if the previous file contained an spdx Id or not 32 if parser.file != nil && parser.file.FileSPDXIdentifier == nullSpdxElementId2_3 { 33 return fmt.Errorf("file with FileName %s does not have SPDX identifier", parser.file.FileName) 34 } 35 parser.file = nil 36 return parser.parsePairFromPackage2_3(tag, value) 37 // tag for going on to snippet section 38 case "SnippetSPDXID": 39 parser.st = psSnippet2_3 40 return parser.parsePairFromSnippet2_3(tag, value) 41 // tag for going on to other license section 42 case "LicenseID": 43 parser.st = psOtherLicense2_3 44 return parser.parsePairFromOtherLicense2_3(tag, value) 45 // tags for file data 46 case "SPDXID": 47 eID, err := extractElementID(value) 48 if err != nil { 49 return err 50 } 51 parser.file.FileSPDXIdentifier = eID 52 if parser.pkg == nil { 53 if parser.doc.Files == nil { 54 parser.doc.Files = []*v2_3.File{} 55 } 56 parser.doc.Files = append(parser.doc.Files, parser.file) 57 } else { 58 if parser.pkg.Files == nil { 59 parser.pkg.Files = []*v2_3.File{} 60 } 61 parser.pkg.Files = append(parser.pkg.Files, parser.file) 62 } 63 case "FileType": 64 parser.file.FileTypes = append(parser.file.FileTypes, value) 65 case "FileChecksum": 66 subkey, subvalue, err := extractSubs(value) 67 if err != nil { 68 return err 69 } 70 if parser.file.Checksums == nil { 71 parser.file.Checksums = []common.Checksum{} 72 } 73 switch common.ChecksumAlgorithm(subkey) { 74 case common.SHA1, 75 common.SHA224, 76 common.SHA256, 77 common.SHA384, 78 common.SHA512, 79 common.MD2, 80 common.MD4, 81 common.MD5, 82 common.MD6, 83 common.SHA3_256, 84 common.SHA3_384, 85 common.SHA3_512, 86 common.BLAKE2b_256, 87 common.BLAKE2b_384, 88 common.BLAKE2b_512, 89 common.BLAKE3, 90 common.ADLER32: 91 algorithm := common.ChecksumAlgorithm(subkey) 92 parser.file.Checksums = append(parser.file.Checksums, common.Checksum{Algorithm: algorithm, Value: subvalue}) 93 default: 94 return fmt.Errorf("got unknown checksum type %s", subkey) 95 } 96 case "LicenseConcluded": 97 parser.file.LicenseConcluded = value 98 case "LicenseInfoInFile": 99 parser.file.LicenseInfoInFiles = append(parser.file.LicenseInfoInFiles, value) 100 case "LicenseComments": 101 parser.file.LicenseComments = value 102 case "FileCopyrightText": 103 parser.file.FileCopyrightText = value 104 case "ArtifactOfProjectName": 105 parser.fileAOP = &v2_3.ArtifactOfProject{} 106 parser.file.ArtifactOfProjects = append(parser.file.ArtifactOfProjects, parser.fileAOP) 107 parser.fileAOP.Name = value 108 case "ArtifactOfProjectHomePage": 109 if parser.fileAOP == nil { 110 return fmt.Errorf("no current ArtifactOfProject found") 111 } 112 parser.fileAOP.HomePage = value 113 case "ArtifactOfProjectURI": 114 if parser.fileAOP == nil { 115 return fmt.Errorf("no current ArtifactOfProject found") 116 } 117 parser.fileAOP.URI = value 118 case "FileComment": 119 parser.file.FileComment = value 120 case "FileNotice": 121 parser.file.FileNotice = value 122 case "FileContributor": 123 parser.file.FileContributors = append(parser.file.FileContributors, value) 124 case "FileDependency": 125 parser.file.FileDependencies = append(parser.file.FileDependencies, value) 126 case "FileAttributionText": 127 parser.file.FileAttributionTexts = append(parser.file.FileAttributionTexts, value) 128 // for relationship tags, pass along but don't change state 129 case "Relationship": 130 parser.rln = &v2_3.Relationship{} 131 parser.doc.Relationships = append(parser.doc.Relationships, parser.rln) 132 return parser.parsePairForRelationship2_3(tag, value) 133 case "RelationshipComment": 134 return parser.parsePairForRelationship2_3(tag, value) 135 // for annotation tags, pass along but don't change state 136 case "Annotator": 137 parser.ann = &v2_3.Annotation{} 138 parser.doc.Annotations = append(parser.doc.Annotations, parser.ann) 139 return parser.parsePairForAnnotation2_3(tag, value) 140 case "AnnotationDate": 141 return parser.parsePairForAnnotation2_3(tag, value) 142 case "AnnotationType": 143 return parser.parsePairForAnnotation2_3(tag, value) 144 case "SPDXREF": 145 return parser.parsePairForAnnotation2_3(tag, value) 146 case "AnnotationComment": 147 return parser.parsePairForAnnotation2_3(tag, value) 148 // tag for going on to review section (DEPRECATED) 149 case "Reviewer": 150 parser.st = psReview2_3 151 return parser.parsePairFromReview2_3(tag, value) 152 default: 153 return fmt.Errorf("received unknown tag %v in File section", tag) 154 } 155 156 return nil 157} 158