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