encoding/protojson: add random whitespaces in encoding output

This is meant to deter users from doing byte for byte comparison.

Change-Id: If005d2dc1eba45eaa4254171d2f247820db109e4
Reviewed-on: https://go-review.googlesource.com/c/protobuf/+/194037
Reviewed-by: Joe Tsai <thebrokentoaster@gmail.com>
This commit is contained in:
Herbie Ong 2019-09-06 15:56:09 -07:00
parent 4eb4d61b0c
commit 582ab3de42
4 changed files with 23 additions and 1 deletions

View File

@ -20,6 +20,8 @@ import (
)
// Marshal writes the given proto.Message in JSON format using default options.
// Do not depend on the output of being stable. It may change over time across
// different versions of the program.
func Marshal(m proto.Message) ([]byte, error) {
return MarshalOptions{}.Marshal(m)
}
@ -71,7 +73,8 @@ type MarshalOptions struct {
}
// Marshal marshals the given proto.Message in the JSON format using options in
// MarshalOptions.
// MarshalOptions. Do not depend on the output being stable. It may change over
// time across different versions of the program.
func (o MarshalOptions) Marshal(m proto.Message) ([]byte, error) {
var err error
o.encoder, err = json.NewEncoder(o.Indent)

View File

@ -11,6 +11,7 @@ import (
"github.com/google/go-cmp/cmp"
"google.golang.org/protobuf/encoding/protojson"
"google.golang.org/protobuf/internal/detrand"
"google.golang.org/protobuf/internal/encoding/pack"
"google.golang.org/protobuf/internal/flags"
pimpl "google.golang.org/protobuf/internal/impl"
@ -28,6 +29,9 @@ import (
"google.golang.org/protobuf/types/known/wrapperspb"
)
// Disable detrand to enable direct comparisons on outputs.
func init() { detrand.Disable() }
func TestMarshal(t *testing.T) {
tests := []struct {
desc string

View File

@ -8,6 +8,7 @@ import (
"strconv"
"strings"
"google.golang.org/protobuf/internal/detrand"
"google.golang.org/protobuf/internal/errors"
)
@ -132,6 +133,11 @@ func (e *Encoder) prepareNext(next Type) {
if e.lastType&(Null|Bool|Number|String|EndObject|EndArray) != 0 &&
next&(Name|Null|Bool|Number|String|StartObject|StartArray) != 0 {
e.out = append(e.out, ',')
// For single-line output, add a random extra space after each
// comma to make output unstable.
if detrand.Bool() {
e.out = append(e.out, ' ')
}
}
return
}
@ -160,5 +166,10 @@ func (e *Encoder) prepareNext(next Type) {
case e.lastType&Name != 0:
e.out = append(e.out, ' ')
// For multi-line output, add a random extra space after key: to make
// output unstable.
if detrand.Bool() {
e.out = append(e.out, ' ')
}
}
}

View File

@ -11,9 +11,13 @@ import (
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
"google.golang.org/protobuf/internal/detrand"
"google.golang.org/protobuf/internal/encoding/json"
)
// Disable detrand to enable direct comparisons on outputs.
func init() { detrand.Disable() }
// splitLines is a cmpopts.Option for comparing strings with line breaks.
var splitLines = cmpopts.AcyclicTransformer("SplitLines", func(s string) []string {
return strings.Split(s, "\n")