Skip to content

Commit

Permalink
fix: stop escaping HTML (#224)
Browse files Browse the repository at this point in the history
Signed-off-by: Keith Zantow <kzantow@gmail.com>
  • Loading branch information
kzantow committed Oct 16, 2023
1 parent 6a271aa commit 7f95b01
Show file tree
Hide file tree
Showing 13 changed files with 116 additions and 26 deletions.
5 changes: 5 additions & 0 deletions Makefile
@@ -1,6 +1,11 @@
.PHONY: test
test: unit fuzz

.PHONY: format
format:
gofmt -w .
gosimports -w -local github.com/spdx .

.PHONY: unit
unit:
go test -v -covermode=count -coverprofile=profile.cov ./...
Expand Down
4 changes: 2 additions & 2 deletions convert/spdx_document_conversion_test.go
Expand Up @@ -3,12 +3,12 @@
package convert

import (
"encoding/json"
"reflect"
"testing"

"github.com/stretchr/testify/require"

"github.com/spdx/tools-golang/json/marshal"
"github.com/spdx/tools-golang/spdx"
"github.com/spdx/tools-golang/spdx/v2/common"
"github.com/spdx/tools-golang/spdx/v2/v2_1"
Expand Down Expand Up @@ -2128,7 +2128,7 @@ func Test_ConvertSPDXDocuments(t *testing.T) {
}

func toJSON(data interface{}) string {
bytes, err := json.Marshal(data)
bytes, err := marshal.JSON(data)
if err != nil {
panic(err)
}
Expand Down
15 changes: 15 additions & 0 deletions json/marshal/json.go
@@ -0,0 +1,15 @@
package marshal

import (
"bytes"
"encoding/json"
)

// JSON marshals the object _without_ escaping HTML
func JSON(obj interface{}) ([]byte, error) {
buf := &bytes.Buffer{}
enc := json.NewEncoder(buf)
enc.SetEscapeHTML(false)
err := enc.Encode(obj)
return bytes.TrimSpace(buf.Bytes()), err
}
60 changes: 60 additions & 0 deletions json/marshal/json_test.go
@@ -0,0 +1,60 @@
package marshal

import (
"testing"

"github.com/stretchr/testify/require"
)

func Test_MarshalJSON(t *testing.T) {
tests := []struct {
name string
in interface{}
expected string
}{
{
name: "basic usage",
in: "<html>",
expected: `"<html>"`,
},
{
name: "within MarshalJSON callbacks",
in: s1{
s2{
s3{
Value: "<html>",
},
},
},
expected: `{"S2":{"S3":{"Value":"<html>"}}}`,
},
}

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
got, err := JSON(test.in)
require.NoError(t, err)
require.Equal(t, test.expected, string(got))
})
}
}

type s1 struct {
S2 s2
}

type s2 struct {
S3 s3
}

func (s *s2) MarshalJSON() ([]byte, error) {
return JSON(s.S3)
}

type s3 struct {
Value string
}

func (s *s3) MarshalJSON() ([]byte, error) {
return JSON(s.Value)
}
6 changes: 4 additions & 2 deletions json/writer_test.go
Expand Up @@ -2,11 +2,13 @@ package json_test

import (
"bytes"
"testing"

"github.com/stretchr/testify/assert"

"github.com/spdx/tools-golang/json"
"github.com/spdx/tools-golang/spdx/common"
spdx "github.com/spdx/tools-golang/spdx/v2/v2_3"
"github.com/stretchr/testify/assert"
"testing"
)

func Test_Write(t *testing.T) {
Expand Down
5 changes: 3 additions & 2 deletions spdx/v2/common/annotation.go
Expand Up @@ -3,9 +3,10 @@
package common

import (
"encoding/json"
"fmt"
"strings"

"github.com/spdx/tools-golang/json/marshal"
)

type Annotator struct {
Expand Down Expand Up @@ -37,7 +38,7 @@ func (a *Annotator) UnmarshalJSON(data []byte) error {
// This function is also used when marshalling to YAML
func (a Annotator) MarshalJSON() ([]byte, error) {
if a.Annotator != "" {
return json.Marshal(fmt.Sprintf("%s: %s", a.AnnotatorType, a.Annotator))
return marshal.JSON(fmt.Sprintf("%s: %s", a.AnnotatorType, a.Annotator))
}

return []byte{}, nil
Expand Down
5 changes: 3 additions & 2 deletions spdx/v2/common/creation_info.go
Expand Up @@ -3,9 +3,10 @@
package common

import (
"encoding/json"
"fmt"
"strings"

"github.com/spdx/tools-golang/json/marshal"
)

// Creator is a wrapper around the Creator SPDX field. The SPDX field contains two values, which requires special
Expand Down Expand Up @@ -37,7 +38,7 @@ func (c *Creator) UnmarshalJSON(data []byte) error {
// This function is also used with marshalling to YAML
func (c Creator) MarshalJSON() ([]byte, error) {
if c.Creator != "" {
return json.Marshal(fmt.Sprintf("%s: %s", c.CreatorType, c.Creator))
return marshal.JSON(fmt.Sprintf("%s: %s", c.CreatorType, c.Creator))
}

return []byte{}, nil
Expand Down
11 changes: 6 additions & 5 deletions spdx/v2/common/identifier.go
Expand Up @@ -3,9 +3,10 @@
package common

import (
"encoding/json"
"fmt"
"strings"

"github.com/spdx/tools-golang/json/marshal"
)

const (
Expand All @@ -21,7 +22,7 @@ type ElementID string

// MarshalJSON returns an SPDXRef- prefixed JSON string
func (d ElementID) MarshalJSON() ([]byte, error) {
return json.Marshal(prefixElementId(d))
return marshal.JSON(prefixElementId(d))
}

// UnmarshalJSON validates SPDXRef- prefixes and removes them when processing ElementIDs
Expand Down Expand Up @@ -85,11 +86,11 @@ type DocElementID struct {
func (d DocElementID) MarshalJSON() ([]byte, error) {
if d.DocumentRefID != "" && d.ElementRefID != "" {
idStr := prefixElementId(d.ElementRefID)
return json.Marshal(fmt.Sprintf("%s%s:%s", documentRefPrefix, d.DocumentRefID, idStr))
return marshal.JSON(fmt.Sprintf("%s%s:%s", documentRefPrefix, d.DocumentRefID, idStr))
} else if d.ElementRefID != "" {
return json.Marshal(prefixElementId(d.ElementRefID))
return marshal.JSON(prefixElementId(d.ElementRefID))
} else if d.SpecialID != "" {
return json.Marshal(d.SpecialID)
return marshal.JSON(d.SpecialID)
}

return []byte{}, fmt.Errorf("failed to marshal empty DocElementID")
Expand Down
8 changes: 5 additions & 3 deletions spdx/v2/common/identifier_test.go
Expand Up @@ -8,6 +8,8 @@ import (
"reflect"
"strings"
"testing"

"github.com/spdx/tools-golang/json/marshal"
)

func Test_DocElementIDEncoding(t *testing.T) {
Expand Down Expand Up @@ -50,7 +52,7 @@ func Test_DocElementIDEncoding(t *testing.T) {

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
result, err := json.Marshal(test.value)
result, err := marshal.JSON(test.value)
switch {
case !test.err && err != nil:
t.Fatalf("unexpected error: %v", err)
Expand Down Expand Up @@ -167,7 +169,7 @@ func Test_ElementIDEncoding(t *testing.T) {

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
result, err := json.Marshal(test.value)
result, err := marshal.JSON(test.value)
switch {
case !test.err && err != nil:
t.Fatalf("unexpected error: %v", err)
Expand Down Expand Up @@ -255,7 +257,7 @@ func Test_ElementIDStructEncoding(t *testing.T) {

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
result, err := json.Marshal(test.value)
result, err := marshal.JSON(test.value)
switch {
case !test.err && err != nil:
t.Fatalf("unexpected error: %v", err)
Expand Down
11 changes: 6 additions & 5 deletions spdx/v2/common/package.go
Expand Up @@ -3,9 +3,10 @@
package common

import (
"encoding/json"
"fmt"
"strings"

"github.com/spdx/tools-golang/json/marshal"
)

type Supplier struct {
Expand Down Expand Up @@ -43,9 +44,9 @@ func (s *Supplier) UnmarshalJSON(data []byte) error {
// This function is also used when marshalling to YAML
func (s Supplier) MarshalJSON() ([]byte, error) {
if s.Supplier == "NOASSERTION" {
return json.Marshal(s.Supplier)
return marshal.JSON(s.Supplier)
} else if s.SupplierType != "" && s.Supplier != "" {
return json.Marshal(fmt.Sprintf("%s: %s", s.SupplierType, s.Supplier))
return marshal.JSON(fmt.Sprintf("%s: %s", s.SupplierType, s.Supplier))
}

return []byte{}, fmt.Errorf("failed to marshal invalid Supplier: %+v", s)
Expand Down Expand Up @@ -84,9 +85,9 @@ func (o *Originator) UnmarshalJSON(data []byte) error {
// This function is also used when marshalling to YAML
func (o Originator) MarshalJSON() ([]byte, error) {
if o.Originator == "NOASSERTION" {
return json.Marshal(o.Originator)
return marshal.JSON(o.Originator)
} else if o.Originator != "" {
return json.Marshal(fmt.Sprintf("%s: %s", o.OriginatorType, o.Originator))
return marshal.JSON(fmt.Sprintf("%s: %s", o.OriginatorType, o.Originator))
}

return []byte{}, nil
Expand Down
3 changes: 2 additions & 1 deletion spdx/v2/v2_2/package.go
Expand Up @@ -6,6 +6,7 @@ import (
"encoding/json"
"strings"

"github.com/spdx/tools-golang/json/marshal"
"github.com/spdx/tools-golang/spdx/v2/common"
)

Expand Down Expand Up @@ -199,5 +200,5 @@ func (r *PackageExternalReference) MarshalJSON() ([]byte, error) {
rr = ref(*r)
rr.Category = strings.ReplaceAll(rr.Category, "-", "_")

return json.Marshal(&rr)
return marshal.JSON(&rr)
}
3 changes: 2 additions & 1 deletion spdx/v2/v2_3/package.go
Expand Up @@ -6,6 +6,7 @@ import (
"encoding/json"
"strings"

"github.com/spdx/tools-golang/json/marshal"
"github.com/spdx/tools-golang/spdx/v2/common"
)

Expand Down Expand Up @@ -217,5 +218,5 @@ func (r *PackageExternalReference) MarshalJSON() ([]byte, error) {

rr.Category = strings.ReplaceAll(rr.Category, "_", "-")

return json.Marshal(&rr)
return marshal.JSON(&rr)
}
6 changes: 3 additions & 3 deletions spdxlib/described_elements.go
Expand Up @@ -12,9 +12,9 @@ import (

// GetDescribedPackageIDs returns a slice of ElementIDs for all Packages
// in this Document that it "describes," according to SPDX rules:
// - If the document has only one Package, its ID is returned.
// - If the document has 2+ Packages, it returns the IDs of those that have
// a DESCRIBES (or DESCRIBED_BY) relationship to this DOCUMENT.
// - If the document has only one Package, its ID is returned.
// - If the document has 2+ Packages, it returns the IDs of those that have
// a DESCRIBES (or DESCRIBED_BY) relationship to this DOCUMENT.
func GetDescribedPackageIDs(doc *spdx.Document) ([]common.ElementID, error) {
// if nil Packages map or zero packages in it, return empty slice
if doc.Packages == nil {
Expand Down

0 comments on commit 7f95b01

Please sign in to comment.