Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples/sample-docs/tv/SPDXTagExample-v2.3.spdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ DataLicense: CC0-1.0
SPDXID: SPDXRef-DOCUMENT
DocumentName: SPDX-Tools-v2.0
DocumentNamespace: http://spdx.org/spdxdocs/spdx-example-444504E0-4F89-41D3-9A0C-0305E82C3301
ExternalDocumentRef: DocumentRef-DocumentRef-spdx-tool-1.2 http://spdx.org/spdxdocs/spdx-tools-v1.2-3F2504E0-4F89-41D3-9A0C-0305E82C3301 SHA1:d6a770ba38583ed4bb4525bd96e50461655d2759
ExternalDocumentRef: DocumentRef-spdx-tool-1.2 http://spdx.org/spdxdocs/spdx-tools-v1.2-3F2504E0-4F89-41D3-9A0C-0305E82C3301 SHA1:d6a770ba38583ed4bb4525bd96e50461655d2759
DocumentComment: This document was created using SPDX 2.0 using licenses from the web site.
LicenseListVersion: 3.9
Creator: Tool: LicenseFind-1.0
Expand Down
71 changes: 57 additions & 14 deletions spdx/v2/common/identifier.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,50 @@ const (
documentRefPrefix = "DocumentRef-"
)

// DocumentID represents the identifier string portion of an SPDX document
// identifier. DocumentID should be used for reference to a SPDX document.
// DocumentIDs should NOT contain the mandatory 'DocumentRef-' portion.
type DocumentID string

// MarshalJSON returns an DocumentRef- prefixed JSON string
func (d DocumentID) MarshalJSON() ([]byte, error) {
return marshal.JSON(prefixDocumentId(d))
}

// UnmarshalJSON validates DocumentRef- prefixes and removes them when processing DocumentIDs
func (d *DocumentID) UnmarshalJSON(data []byte) error {
// SPDX identifier will simply be a string
idStr := string(data)
idStr = strings.Trim(idStr, "\"")

e, err := trimDocumentIdPrefix(idStr)
if err != nil {
return err
}
*d = e
return nil
}

// prefixDocumentId adds the DocumentRef- prefix to an document ID if it does not have one
func prefixDocumentId(id DocumentID) string {
val := string(id)
if !strings.HasPrefix(val, spdxRefPrefix) {
return documentRefPrefix + val
}
return val
}

// trimDocumentIdPrefix removes the DocumentRef- prefix from an document ID string or returns an error if it
// does not start with DocumentRef-
func trimDocumentIdPrefix(id string) (DocumentID, error) {
// handle DocumentRef-
if !strings.HasPrefix(id, documentRefPrefix) {
return "", fmt.Errorf("failed to parse SPDX identifier '%s'", id)
}
e := DocumentID(strings.TrimPrefix(id, documentRefPrefix))
return e, nil
}

// ElementID represents the identifier string portion of an SPDX element
// identifier. DocElementID should be used for any attributes which can
// contain identifiers defined in a different SPDX document.
Expand Down Expand Up @@ -52,12 +96,10 @@ func prefixElementId(id ElementID) string {
// does not start with SPDXRef-
func trimElementIdPrefix(id string) (ElementID, error) {
// handle SPDXRef-
idFields := strings.SplitN(id, spdxRefPrefix, 2)
if len(idFields) != 2 {
if !strings.HasPrefix(id, spdxRefPrefix) {
return "", fmt.Errorf("failed to parse SPDX identifier '%s'", id)
}

e := ElementID(idFields[1])
e := ElementID(strings.TrimPrefix(id, spdxRefPrefix))
return e, nil
}

Expand All @@ -76,7 +118,7 @@ func trimElementIdPrefix(id string) (ElementID, error) {
// "NOASSERTION" for the right-hand side of Relationships. If SpecialID
// is set, DocumentRefID and ElementRefID should be empty (and vice versa).
type DocElementID struct {
DocumentRefID string
DocumentRefID DocumentID
ElementRefID ElementID
SpecialID string
}
Expand All @@ -85,8 +127,9 @@ type DocElementID struct {
// This function is also used when marshalling to YAML
func (d DocElementID) MarshalJSON() ([]byte, error) {
if d.DocumentRefID != "" && d.ElementRefID != "" {
idStr := prefixElementId(d.ElementRefID)
return marshal.JSON(fmt.Sprintf("%s%s:%s", documentRefPrefix, d.DocumentRefID, idStr))
dIdStr := prefixDocumentId(d.DocumentRefID)
eIdStr := prefixElementId(d.ElementRefID)
return marshal.JSON(fmt.Sprintf("%s:%s", dIdStr, eIdStr))
} else if d.ElementRefID != "" {
return marshal.JSON(prefixElementId(d.ElementRefID))
} else if d.SpecialID != "" {
Expand All @@ -112,13 +155,13 @@ func (d *DocElementID) UnmarshalJSON(data []byte) (err error) {
var idFields []string
// handle DocumentRef- if present
if strings.HasPrefix(idStr, documentRefPrefix) {
// strip out the "DocumentRef-" so we can get the value
idFields = strings.SplitN(idStr, documentRefPrefix, 2)
idStr = idFields[1]

// an SPDXRef can appear after a DocumentRef, separated by a colon
idFields = strings.SplitN(idStr, ":", 2)
d.DocumentRefID = idFields[0]

d.DocumentRefID, err = trimDocumentIdPrefix(idFields[0])
if err != nil {
return err
}

if len(idFields) == 2 {
idStr = idFields[1]
Expand All @@ -139,7 +182,7 @@ func (d *DocElementID) UnmarshalJSON(data []byte) (err error) {
// present document.
func MakeDocElementID(docRef string, eltRef string) DocElementID {
return DocElementID{
DocumentRefID: docRef,
DocumentRefID: DocumentID(docRef),
ElementRefID: ElementID(eltRef),
}
}
Expand Down Expand Up @@ -168,7 +211,7 @@ func RenderDocElementID(deID DocElementID) string {
}
prefix := ""
if deID.DocumentRefID != "" {
prefix = documentRefPrefix + deID.DocumentRefID + ":"
prefix = documentRefPrefix + string(deID.DocumentRefID) + ":"
}
return prefix + spdxRefPrefix + string(deID.ElementRefID)
}
2 changes: 1 addition & 1 deletion spdx/v2/v2_1/document.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ type ExternalDocumentRef struct {
// DocumentRefID is the ID string defined in the start of the
// reference. It should _not_ contain the "DocumentRef-" part
// of the mandatory ID string.
DocumentRefID string `json:"externalDocumentId"`
DocumentRefID common.DocumentID `json:"externalDocumentId"`

// URI is the URI defined for the external document
URI string `json:"spdxDocument"`
Expand Down
2 changes: 1 addition & 1 deletion spdx/v2/v2_1/tagvalue/reader/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ func (parser *tvParser) parsePairFromStart(tag string, value string) error {
return err
}
edr := spdx.ExternalDocumentRef{
DocumentRefID: documentRefID,
DocumentRefID: common.DocumentID(documentRefID),
URI: uri,
Checksum: common.Checksum{Algorithm: common.ChecksumAlgorithm(alg), Value: checksum},
}
Expand Down
2 changes: 1 addition & 1 deletion spdx/v2/v2_1/tagvalue/reader/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ func extractDocElementID(value string) (common.DocElementID, error) {
}

// we're good
return common.DocElementID{DocumentRefID: docRefID, ElementRefID: common.ElementID(eltRefID)}, nil
return common.DocElementID{DocumentRefID: common.DocumentID(docRefID), ElementRefID: common.ElementID(eltRefID)}, nil
}

// used to extract SPDXRef values only from an SPDX Identifier which can point
Expand Down
2 changes: 1 addition & 1 deletion spdx/v2/v2_1/tagvalue/reader/util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ func helperForExtractDocElementID(t *testing.T, tst string, wantErr bool, wantDo
if err == nil && wantErr == true {
t.Errorf("testing %v: expected non-nil error, got nil", tst)
}
if deID.DocumentRefID != wantDoc {
if deID.DocumentRefID != common.DocumentID(wantDoc) {
if wantDoc == "" {
t.Errorf("testing %v: want empty string for DocumentRefID, got %v", tst, deID.DocumentRefID)
} else {
Expand Down
2 changes: 1 addition & 1 deletion spdx/v2/v2_2/document.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ type ExternalDocumentRef struct {
// DocumentRefID is the ID string defined in the start of the
// reference. It should _not_ contain the "DocumentRef-" part
// of the mandatory ID string.
DocumentRefID string `json:"externalDocumentId"`
DocumentRefID common.DocumentID `json:"externalDocumentId"`

// URI is the URI defined for the external document
URI string `json:"spdxDocument"`
Expand Down
2 changes: 1 addition & 1 deletion spdx/v2/v2_2/example/example.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ var example = spdx.Document{
DocumentComment: "This document was created using SPDX 2.0 using licenses from the web site.",
ExternalDocumentReferences: []spdx.ExternalDocumentRef{
{
DocumentRefID: "DocumentRef-spdx-tool-1.2",
DocumentRefID: "spdx-tool-1.2",
URI: "http://spdx.org/spdxdocs/spdx-tools-v1.2-3F2504E0-4F89-41D3-9A0C-0305E82C3301",
Checksum: common.Checksum{
Algorithm: common.SHA1,
Expand Down
2 changes: 1 addition & 1 deletion spdx/v2/v2_2/rdf/reader/parse_spdx_document.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ func (parser *rdfParser2_2) getExternalDocumentRefFromNode(node *gordfParser.Nod
switch triple.Predicate.ID {
case SPDX_EXTERNAL_DOCUMENT_ID:
// cardinality: exactly 1
edr.DocumentRefID = triple.Object.ID
edr.DocumentRefID = common.DocumentID(triple.Object.ID)
case SPDX_SPDX_DOCUMENT:
// cardinality: exactly 1
// assumption: "spdxDocument" property of an external document
Expand Down
2 changes: 1 addition & 1 deletion spdx/v2/v2_2/rdf/reader/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ func ExtractDocElementID(value string) (common.DocElementID, error) {
}

// we're good
return common.DocElementID{DocumentRefID: docRefID, ElementRefID: common.ElementID(eltRefID)}, nil
return common.DocElementID{DocumentRefID: common.DocumentID(docRefID), ElementRefID: common.ElementID(eltRefID)}, nil
}

// used to extract SPDXRef values only from an SPDX Identifier which can point
Expand Down
2 changes: 1 addition & 1 deletion spdx/v2/v2_2/rdf/reader/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ func helperForExtractDocElementID(t *testing.T, tst string, wantErr bool, wantDo
if err == nil && wantErr == true {
t.Errorf("testing %v: expected non-nil error, got nil", tst)
}
if deID.DocumentRefID != wantDoc {
if deID.DocumentRefID != common.DocumentID(wantDoc) {
if wantDoc == "" {
t.Errorf("testing %v: want empty string for DocumentRefID, got %v", tst, deID.DocumentRefID)
} else {
Expand Down
2 changes: 1 addition & 1 deletion spdx/v2/v2_2/tagvalue/reader/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ func (parser *tvParser) parsePairFromStart(tag string, value string) error {
return err
}
edr := spdx.ExternalDocumentRef{
DocumentRefID: documentRefID,
DocumentRefID: common.DocumentID(documentRefID),
URI: uri,
Checksum: common.Checksum{Algorithm: common.ChecksumAlgorithm(alg), Value: checksum},
}
Expand Down
2 changes: 1 addition & 1 deletion spdx/v2/v2_2/tagvalue/reader/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ func extractDocElementID(value string) (common.DocElementID, error) {
}

// we're good
return common.DocElementID{DocumentRefID: docRefID, ElementRefID: common.ElementID(eltRefID)}, nil
return common.DocElementID{DocumentRefID: common.DocumentID(docRefID), ElementRefID: common.ElementID(eltRefID)}, nil
}

// used to extract SPDXRef values from an SPDX Identifier, OR "special" strings
Expand Down
4 changes: 2 additions & 2 deletions spdx/v2/v2_2/tagvalue/reader/util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ func helperForExtractDocElementID(t *testing.T, tst string, wantErr bool, wantDo
if err == nil && wantErr == true {
t.Errorf("testing %v: expected non-nil error, got nil", tst)
}
if deID.DocumentRefID != wantDoc {
if deID.DocumentRefID != common.DocumentID(wantDoc) {
if wantDoc == "" {
t.Errorf("testing %v: want empty string for DocumentRefID, got %v", tst, deID.DocumentRefID)
} else {
Expand Down Expand Up @@ -96,7 +96,7 @@ func helperForExtractDocElementSpecial(t *testing.T, permittedSpecial []string,
if err == nil && wantErr == true {
t.Errorf("testing %v: expected non-nil error, got nil", tst)
}
if deID.DocumentRefID != wantDoc {
if deID.DocumentRefID != common.DocumentID(wantDoc) {
if wantDoc == "" {
t.Errorf("testing %v: want empty string for DocumentRefID, got %v", tst, deID.DocumentRefID)
} else {
Expand Down
2 changes: 1 addition & 1 deletion spdx/v2/v2_3/document.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ type ExternalDocumentRef struct {
// DocumentRefID is the ID string defined in the start of the
// reference. It should _not_ contain the "DocumentRef-" part
// of the mandatory ID string.
DocumentRefID string `json:"externalDocumentId"`
DocumentRefID common.DocumentID `json:"externalDocumentId"`

// URI is the URI defined for the external document
URI string `json:"spdxDocument"`
Expand Down
2 changes: 1 addition & 1 deletion spdx/v2/v2_3/example/example.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ var example = spdx.Document{
DocumentComment: "This document was created using SPDX 2.0 using licenses from the web site.",
ExternalDocumentReferences: []spdx.ExternalDocumentRef{
{
DocumentRefID: "DocumentRef-spdx-tool-1.2",
DocumentRefID: "spdx-tool-1.2",
URI: "http://spdx.org/spdxdocs/spdx-tools-v1.2-3F2504E0-4F89-41D3-9A0C-0305E82C3301",
Checksum: common.Checksum{
Algorithm: common.SHA1,
Expand Down
2 changes: 1 addition & 1 deletion spdx/v2/v2_3/rdf/reader/parse_spdx_document.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ func (parser *rdfParser2_3) getExternalDocumentRefFromNode(node *gordfParser.Nod
switch triple.Predicate.ID {
case SPDX_EXTERNAL_DOCUMENT_ID:
// cardinality: exactly 1
edr.DocumentRefID = triple.Object.ID
edr.DocumentRefID = common.DocumentID(triple.Object.ID)
case SPDX_SPDX_DOCUMENT:
// cardinality: exactly 1
// assumption: "spdxDocument" property of an external document
Expand Down
2 changes: 1 addition & 1 deletion spdx/v2/v2_3/rdf/reader/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ func ExtractDocElementID(value string) (common.DocElementID, error) {
}

// we're good
return common.DocElementID{DocumentRefID: docRefID, ElementRefID: common.ElementID(eltRefID)}, nil
return common.DocElementID{DocumentRefID: common.DocumentID(docRefID), ElementRefID: common.ElementID(eltRefID)}, nil
}

// used to extract SPDXRef values only from an SPDX Identifier which can point
Expand Down
2 changes: 1 addition & 1 deletion spdx/v2/v2_3/rdf/reader/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ func helperForExtractDocElementID(t *testing.T, tst string, wantErr bool, wantDo
if err == nil && wantErr == true {
t.Errorf("testing %v: expected non-nil error, got nil", tst)
}
if deID.DocumentRefID != wantDoc {
if deID.DocumentRefID != common.DocumentID(wantDoc) {
if wantDoc == "" {
t.Errorf("testing %v: want empty string for DocumentRefID, got %v", tst, deID.DocumentRefID)
} else {
Expand Down
2 changes: 1 addition & 1 deletion spdx/v2/v2_3/tagvalue/reader/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ func (parser *tvParser) parsePairFromStart(tag string, value string) error {
return err
}
edr := spdx.ExternalDocumentRef{
DocumentRefID: documentRefID,
DocumentRefID: common.DocumentID(documentRefID),
URI: uri,
Checksum: common.Checksum{Algorithm: common.ChecksumAlgorithm(alg), Value: checksum},
}
Expand Down
2 changes: 1 addition & 1 deletion spdx/v2/v2_3/tagvalue/reader/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ func extractDocElementID(value string) (common.DocElementID, error) {
}

// we're good
return common.DocElementID{DocumentRefID: docRefID, ElementRefID: common.ElementID(eltRefID)}, nil
return common.DocElementID{DocumentRefID: common.DocumentID(docRefID), ElementRefID: common.ElementID(eltRefID)}, nil
}

// used to extract SPDXRef values from an SPDX Identifier, OR "special" strings
Expand Down
4 changes: 2 additions & 2 deletions spdx/v2/v2_3/tagvalue/reader/util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ func helperForExtractDocElementID(t *testing.T, tst string, wantErr bool, wantDo
if err == nil && wantErr == true {
t.Errorf("testing %v: expected non-nil error, got nil", tst)
}
if deID.DocumentRefID != wantDoc {
if deID.DocumentRefID != common.DocumentID(wantDoc) {
if wantDoc == "" {
t.Errorf("testing %v: want empty string for DocumentRefID, got %v", tst, deID.DocumentRefID)
} else {
Expand Down Expand Up @@ -96,7 +96,7 @@ func helperForExtractDocElementSpecial(t *testing.T, permittedSpecial []string,
if err == nil && wantErr == true {
t.Errorf("testing %v: expected non-nil error, got nil", tst)
}
if deID.DocumentRefID != wantDoc {
if deID.DocumentRefID != common.DocumentID(wantDoc) {
if wantDoc == "" {
t.Errorf("testing %v: want empty string for DocumentRefID, got %v", tst, deID.DocumentRefID)
} else {
Expand Down