Skip to content

Commit 582ab3d

Browse files
committed
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 <[email protected]>
1 parent 4eb4d61 commit 582ab3d

File tree

4 files changed

+23
-1
lines changed

4 files changed

+23
-1
lines changed

encoding/protojson/encode.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ import (
2020
)
2121

2222
// Marshal writes the given proto.Message in JSON format using default options.
23+
// Do not depend on the output of being stable. It may change over time across
24+
// different versions of the program.
2325
func Marshal(m proto.Message) ([]byte, error) {
2426
return MarshalOptions{}.Marshal(m)
2527
}
@@ -71,7 +73,8 @@ type MarshalOptions struct {
7173
}
7274

7375
// Marshal marshals the given proto.Message in the JSON format using options in
74-
// MarshalOptions.
76+
// MarshalOptions. Do not depend on the output being stable. It may change over
77+
// time across different versions of the program.
7578
func (o MarshalOptions) Marshal(m proto.Message) ([]byte, error) {
7679
var err error
7780
o.encoder, err = json.NewEncoder(o.Indent)

encoding/protojson/encode_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111

1212
"github.com/google/go-cmp/cmp"
1313
"google.golang.org/protobuf/encoding/protojson"
14+
"google.golang.org/protobuf/internal/detrand"
1415
"google.golang.org/protobuf/internal/encoding/pack"
1516
"google.golang.org/protobuf/internal/flags"
1617
pimpl "google.golang.org/protobuf/internal/impl"
@@ -28,6 +29,9 @@ import (
2829
"google.golang.org/protobuf/types/known/wrapperspb"
2930
)
3031

32+
// Disable detrand to enable direct comparisons on outputs.
33+
func init() { detrand.Disable() }
34+
3135
func TestMarshal(t *testing.T) {
3236
tests := []struct {
3337
desc string

internal/encoding/json/encode.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"strconv"
99
"strings"
1010

11+
"google.golang.org/protobuf/internal/detrand"
1112
"google.golang.org/protobuf/internal/errors"
1213
)
1314

@@ -132,6 +133,11 @@ func (e *Encoder) prepareNext(next Type) {
132133
if e.lastType&(Null|Bool|Number|String|EndObject|EndArray) != 0 &&
133134
next&(Name|Null|Bool|Number|String|StartObject|StartArray) != 0 {
134135
e.out = append(e.out, ',')
136+
// For single-line output, add a random extra space after each
137+
// comma to make output unstable.
138+
if detrand.Bool() {
139+
e.out = append(e.out, ' ')
140+
}
135141
}
136142
return
137143
}
@@ -160,5 +166,10 @@ func (e *Encoder) prepareNext(next Type) {
160166

161167
case e.lastType&Name != 0:
162168
e.out = append(e.out, ' ')
169+
// For multi-line output, add a random extra space after key: to make
170+
// output unstable.
171+
if detrand.Bool() {
172+
e.out = append(e.out, ' ')
173+
}
163174
}
164175
}

internal/encoding/json/encode_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,13 @@ import (
1111

1212
"github.com/google/go-cmp/cmp"
1313
"github.com/google/go-cmp/cmp/cmpopts"
14+
"google.golang.org/protobuf/internal/detrand"
1415
"google.golang.org/protobuf/internal/encoding/json"
1516
)
1617

18+
// Disable detrand to enable direct comparisons on outputs.
19+
func init() { detrand.Disable() }
20+
1721
// splitLines is a cmpopts.Option for comparing strings with line breaks.
1822
var splitLines = cmpopts.AcyclicTransformer("SplitLines", func(s string) []string {
1923
return strings.Split(s, "\n")

0 commit comments

Comments
 (0)