1// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later 2 3package parser2v1 4 5import ( 6 "fmt" 7 "strings" 8 9 "github.com/spdx/tools-golang/spdx/common" 10) 11 12// used to extract key / value from embedded substrings 13// returns subkey, subvalue, nil if no error, or "", "", error otherwise 14func extractSubs(value string) (string, string, error) { 15 // parse the value to see if it's a valid subvalue format 16 sp := strings.SplitN(value, ":", 2) 17 if len(sp) == 1 { 18 return "", "", fmt.Errorf("invalid subvalue format for %s (no colon found)", value) 19 } 20 21 subkey := strings.TrimSpace(sp[0]) 22 subvalue := strings.TrimSpace(sp[1]) 23 24 return subkey, subvalue, nil 25} 26 27// used to extract DocumentRef and SPDXRef values from an SPDX Identifier 28// which can point either to this document or to a different one 29func extractDocElementID(value string) (common.DocElementID, error) { 30 docRefID := "" 31 idStr := value 32 33 // check prefix to see if it's a DocumentRef ID 34 if strings.HasPrefix(idStr, "DocumentRef-") { 35 // extract the part that comes between "DocumentRef-" and ":" 36 strs := strings.Split(idStr, ":") 37 // should be exactly two, part before and part after 38 if len(strs) < 2 { 39 return common.DocElementID{}, fmt.Errorf("no colon found although DocumentRef- prefix present") 40 } 41 if len(strs) > 2 { 42 return common.DocElementID{}, fmt.Errorf("more than one colon found") 43 } 44 45 // trim the prefix and confirm non-empty 46 docRefID = strings.TrimPrefix(strs[0], "DocumentRef-") 47 if docRefID == "" { 48 return common.DocElementID{}, fmt.Errorf("document identifier has nothing after prefix") 49 } 50 // and use remainder for element ID parsing 51 idStr = strs[1] 52 } 53 54 // check prefix to confirm it's got the right prefix for element IDs 55 if !strings.HasPrefix(idStr, "SPDXRef-") { 56 return common.DocElementID{}, fmt.Errorf("missing SPDXRef- prefix for element identifier") 57 } 58 59 // make sure no colons are present 60 if strings.Contains(idStr, ":") { 61 // we know this means there was no DocumentRef- prefix, because 62 // we would have handled multiple colons above if it was 63 return common.DocElementID{}, fmt.Errorf("invalid colon in element identifier") 64 } 65 66 // trim the prefix and confirm non-empty 67 eltRefID := strings.TrimPrefix(idStr, "SPDXRef-") 68 if eltRefID == "" { 69 return common.DocElementID{}, fmt.Errorf("element identifier has nothing after prefix") 70 } 71 72 // we're good 73 return common.DocElementID{DocumentRefID: docRefID, ElementRefID: common.ElementID(eltRefID)}, nil 74} 75 76// used to extract SPDXRef values only from an SPDX Identifier which can point 77// to this document only. Use extractDocElementID for parsing IDs that can 78// refer either to this document or a different one. 79func extractElementID(value string) (common.ElementID, error) { 80 // check prefix to confirm it's got the right prefix for element IDs 81 if !strings.HasPrefix(value, "SPDXRef-") { 82 return common.ElementID(""), fmt.Errorf("missing SPDXRef- prefix for element identifier") 83 } 84 85 // make sure no colons are present 86 if strings.Contains(value, ":") { 87 return common.ElementID(""), fmt.Errorf("invalid colon in element identifier") 88 } 89 90 // trim the prefix and confirm non-empty 91 eltRefID := strings.TrimPrefix(value, "SPDXRef-") 92 if eltRefID == "" { 93 return common.ElementID(""), fmt.Errorf("element identifier has nothing after prefix") 94 } 95 96 // we're good 97 return common.ElementID(eltRefID), nil 98} 99