internal/fuzz: add fuzzers for prototext and protojson packages

Change-Id: Iee065070e6a983c303a3551a67fc32f0e94b649e
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/212219
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
diff --git a/internal/fuzz/jsonfuzz/corpus/e619335648415cae976b3200d5a291e8da4b4866 b/internal/fuzz/jsonfuzz/corpus/e619335648415cae976b3200d5a291e8da4b4866
new file mode 100755
index 0000000..f8b6e00
--- /dev/null
+++ b/internal/fuzz/jsonfuzz/corpus/e619335648415cae976b3200d5a291e8da4b4866
@@ -0,0 +1 @@
+{"testAllTypes":{"optionalInt32":1001, "optionalInt64":"1002", "optionalUint32":1003, "optionalUint64":"1004", "optionalSint32":1005, "optionalSint64":"1006", "optionalFixed32":1007, "optionalFixed64":"1008", "optionalSfixed32":1009, "optionalSfixed64":"1010", "optionalFloat":1011.5, "optionalDouble":1012.5, "optionalBool":true, "optionalString":"string", "optionalBytes":"Ynl0ZXM=", "optionalgroup":{"a":1017}, "optionalNestedMessage":{"a":42, "corecursive":{"optionalInt32":43}}, "optionalNestedEnum":"BAR", "repeatedInt32":[1001, 2001], "repeatedInt64":["1002", "2002"], "repeatedUint32":[1003, 2003], "repeatedUint64":["1004", "2004"], "repeatedSint32":[1005, 2005], "repeatedSint64":["1006", "2006"], "repeatedFixed32":[1007, 2007], "repeatedFixed64":["1008", "2008"], "repeatedSfixed32":[1009, 2009], "repeatedSfixed64":["1010", "2010"], "repeatedFloat":[1011.5, 2011.5], "repeatedDouble":[1012.5, 2012.5], "repeatedBool":[true, false], "repeatedString":["foo", "bar"], "repeatedBytes":["Rk9P", "QkFS"], "repeatedgroup":[{"a":1017}, {}, {"a":2017}], "repeatedNestedMessage":[{"a":1}, {}, {"a":2}], "repeatedNestedEnum":["FOO", "BAR"], "mapInt32Int32":{"1056":1156, "2056":2156}, "mapInt64Int64":{"1057":"1157", "2057":"2157"}, "mapUint32Uint32":{"1058":1158, "2058":2158}, "mapUint64Uint64":{"1059":"1159", "2059":"2159"}, "mapSint32Sint32":{"1060":1160, "2060":2160}, "mapSint64Sint64":{"1061":"1161", "2061":"2161"}, "mapFixed32Fixed32":{"1062":1162, "2062":2162}, "mapFixed64Fixed64":{"1063":"1163", "2063":"2163"}, "mapSfixed32Sfixed32":{"1064":1164, "2064":2164}, "mapSfixed64Sfixed64":{"1065":"1165", "2065":"2165"}, "mapInt32Float":{"1066":1166.5, "2066":2166.5}, "mapInt32Double":{"1067":1167.5, "2067":2167.5}, "mapBoolBool":{"false":true, "true":false}, "mapStringString":{"69.1.key":"69.1.val", "69.2.key":"69.2.val"}, "mapStringBytes":{"70.1.key":"NzAuMS52YWw=", "70.2.key":"NzAuMi52YWw="}, "mapStringNestedMessage":{"71.1.key":{"a":1171}, "71.2.key":{"a":2171}}, "mapStringNestedEnum":{"73.1.key":"FOO", "73.2.key":"BAR"}, "oneofUint32":1111}}
\ No newline at end of file
diff --git a/internal/fuzz/jsonfuzz/fuzz.go b/internal/fuzz/jsonfuzz/fuzz.go
new file mode 100644
index 0000000..969ad6d
--- /dev/null
+++ b/internal/fuzz/jsonfuzz/fuzz.go
@@ -0,0 +1,39 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package textfuzz includes a fuzzer for the text marshaler and unmarshaler.
+package textfuzz
+
+import (
+	"google.golang.org/protobuf/encoding/protojson"
+	"google.golang.org/protobuf/proto"
+
+	fuzzpb "google.golang.org/protobuf/internal/testprotos/fuzz"
+)
+
+// Fuzz is a fuzzer for proto.Marshal and proto.Unmarshal.
+func Fuzz(data []byte) (score int) {
+	m1 := &fuzzpb.Fuzz{}
+	if err := (protojson.UnmarshalOptions{
+		AllowPartial: true,
+	}).Unmarshal(data, m1); err != nil {
+		return 0
+	}
+	data1, err := protojson.MarshalOptions{
+		AllowPartial: true,
+	}.Marshal(m1)
+	if err != nil {
+		panic(err)
+	}
+	m2 := &fuzzpb.Fuzz{}
+	if err := (protojson.UnmarshalOptions{
+		AllowPartial: true,
+	}).Unmarshal(data1, m2); err != nil {
+		return 0
+	}
+	if !proto.Equal(m1, m2) {
+		panic("not equal")
+	}
+	return 1
+}
diff --git a/internal/fuzz/jsonfuzz/fuzz_test.go b/internal/fuzz/jsonfuzz/fuzz_test.go
new file mode 100644
index 0000000..a0e9d0c
--- /dev/null
+++ b/internal/fuzz/jsonfuzz/fuzz_test.go
@@ -0,0 +1,34 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package textfuzz
+
+import (
+	"io/ioutil"
+	"os"
+	"path/filepath"
+	"testing"
+)
+
+func Test(t *testing.T) {
+	dir, err := os.Open("corpus")
+	if err != nil {
+		t.Fatal(err)
+	}
+	infos, err := dir.Readdir(0)
+	if err != nil {
+		t.Fatal(err)
+
+	}
+	for _, info := range infos {
+		name := info.Name()
+		t.Run(name, func(t *testing.T) {
+			b, err := ioutil.ReadFile(filepath.Join("corpus", name))
+			if err != nil {
+				t.Fatal(err)
+			}
+			Fuzz(b)
+		})
+	}
+}