Repository: fxamacker/cbor (go)

Issue:
bug: encoding cbor.RawTag with empty content returns malformed CBOR data 
### What version of fxamacker/cbor are you using?

v2.2.0

### Does this issue reproduce with the latest release?

Yes

### What OS and CPU architecture are you using (`go env`)?

<details><summary><code>go env</code> Output</summary><br><pre>
$ go env
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/user/.cache/go-build"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/user/go"
GOPROXY=""
GORACE=""
GOROOT="/usr/local/go"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build778508732=/tmp/go-build -gno-record-gcc-switches"
</pre></details>

### What did you do?

Encode cbor.RawTag with empty content.

```
rtag := cbor.RawTag{Number: 100} // RawTag.Content is empty
b, err = cbor.Marshal(rtag)
fmt.Printf("Marshal(%+v) returns 0x%x, error %v\n", rtag, b, err)
// Marshal({Number:100 Content:[]}) returns 0xd864, error <nil>
```

### What did you expect to see?

Encoding cbor.RawTag should return either valid CBOR data or error.

### What did you see instead?

See comments in code snippet in previous section.

Pull request:
Fix encoding cbor.RawTag with empty content
Encoding cbor.RawTag with empty content returns CBOR representation of tag_number(null).

Closes #258



Patch:
diff --git a/tag.go b/tag.go
index 924f74d..db29149 100644
--- a/tag.go
+++ b/tag.go
@@ -60,9 +60,14 @@ func (t RawTag) MarshalCBOR() ([]byte, error) {
 
 	encodeHead(e, byte(cborTypeTag), t.Number)
 
-	buf := make([]byte, len(e.Bytes())+len(t.Content))
+	content := t.Content
+	if len(content) == 0 {
+		content = cborNil
+	}
+
+	buf := make([]byte, len(e.Bytes())+len(content))
 	n := copy(buf, e.Bytes())
-	copy(buf[n:], t.Content)
+	copy(buf[n:], content)
 
 	putEncoderBuffer(e)
 	return buf, nil


Test patch:
diff --git a/tag_test.go b/tag_test.go
index f8322b8..560af47 100644
--- a/tag_test.go
+++ b/tag_test.go
@@ -1215,6 +1215,30 @@ func TestMarshalUninitializedRawTag(t *testing.T) {
 	}
 }
 
+func TestMarshalTagWithEmptyContent(t *testing.T) {
+	v := Tag{Number: 100}       // Tag.Content is empty
+	want := hexDecode("d864f6") // 100(null)
+	b, err := Marshal(v)
+	if err != nil {
+		t.Errorf("Marshal(%v) returned error %v", v, err)
+	}
+	if !bytes.Equal(b, want) {
+		t.Errorf("Marshal(%v) = 0x%x, want 0x%x", v, b, want)
+	}
+}
+
+func TestMarshalRawTagWithEmptyContent(t *testing.T) {
+	v := RawTag{Number: 100}    // RawTag.Content is empty
+	want := hexDecode("d864f6") // 100(null)
+	b, err := Marshal(v)
+	if err != nil {
+		t.Errorf("Marshal(%v) returned error %v", v, err)
+	}
+	if !bytes.Equal(b, want) {
+		t.Errorf("Marshal(%v) = 0x%x, want 0x%x", v, b, want)
+	}
+}
+
 func TestEncodeTag(t *testing.T) {
 	m := make(map[interface{}]bool)
 	m[10] = true