@@ -60,6 +60,8 @@ type partialDoc struct {
60
60
self * lazyNode
61
61
keys []string
62
62
obj map [string ]* lazyNode
63
+
64
+ opts * ApplyOptions
63
65
}
64
66
65
67
type partialArray struct {
@@ -90,6 +92,8 @@ type ApplyOptions struct {
90
92
// EnsurePathExistsOnAdd instructs json-patch to recursively create the missing parts of path on "add" operation.
91
93
// Default to false.
92
94
EnsurePathExistsOnAdd bool
95
+
96
+ EscapeHTML bool
93
97
}
94
98
95
99
// NewApplyOptions creates a default set of options for calls to ApplyWithOptions.
@@ -99,6 +103,7 @@ func NewApplyOptions() *ApplyOptions {
99
103
AccumulatedCopySizeLimit : AccumulatedCopySizeLimit ,
100
104
AllowMissingPathOnRemove : false ,
101
105
EnsurePathExistsOnAdd : false ,
106
+ EscapeHTML : true ,
102
107
}
103
108
}
104
109
@@ -143,7 +148,7 @@ func (n *partialDoc) TrustMarshalJSON(buf *bytes.Buffer) error {
143
148
return err
144
149
}
145
150
}
146
- key , err := json .Marshal ( k )
151
+ key , err := json .MarshalEscaped ( k , n . opts . EscapeHTML )
147
152
if err != nil {
148
153
return err
149
154
}
@@ -153,7 +158,7 @@ func (n *partialDoc) TrustMarshalJSON(buf *bytes.Buffer) error {
153
158
if err := buf .WriteByte (':' ); err != nil {
154
159
return err
155
160
}
156
- value , err := json .Marshal (n .obj [k ])
161
+ value , err := json .MarshalEscaped (n .obj [k ], n . opts . EscapeHTML )
157
162
if err != nil {
158
163
return err
159
164
}
@@ -194,11 +199,11 @@ func (n *partialArray) RedirectMarshalJSON() (interface{}, error) {
194
199
return n .nodes , nil
195
200
}
196
201
197
- func deepCopy (src * lazyNode ) (* lazyNode , int , error ) {
202
+ func deepCopy (src * lazyNode , options * ApplyOptions ) (* lazyNode , int , error ) {
198
203
if src == nil {
199
204
return nil , 0 , nil
200
205
}
201
- a , err := json .Marshal (src )
206
+ a , err := json .MarshalEscaped (src , options . EscapeHTML )
202
207
if err != nil {
203
208
return nil , 0 , err
204
209
}
@@ -216,7 +221,7 @@ func (n *lazyNode) nextByte() byte {
216
221
return s [0 ]
217
222
}
218
223
219
- func (n * lazyNode ) intoDoc () (* partialDoc , error ) {
224
+ func (n * lazyNode ) intoDoc (options * ApplyOptions ) (* partialDoc , error ) {
220
225
if n .which == eDoc {
221
226
return n .doc , nil
222
227
}
@@ -235,6 +240,7 @@ func (n *lazyNode) intoDoc() (*partialDoc, error) {
235
240
return nil , ErrInvalid
236
241
}
237
242
243
+ n .doc .opts = options
238
244
if err != nil {
239
245
return nil , err
240
246
}
@@ -545,7 +551,7 @@ func findObject(pd *container, path string, options *ApplyOptions) (container, s
545
551
return nil , ""
546
552
}
547
553
} else {
548
- doc , err = next .intoDoc ()
554
+ doc , err = next .intoDoc (options )
549
555
550
556
if err != nil {
551
557
return nil , ""
@@ -750,6 +756,7 @@ func (p Patch) add(doc *container, op Operation, options *ApplyOptions) error {
750
756
} else {
751
757
pd = & partialDoc {
752
758
self : val ,
759
+ opts : options ,
753
760
}
754
761
}
755
762
@@ -855,7 +862,7 @@ func ensurePathExists(pd *container, path string, options *ApplyOptions) error {
855
862
newNode := newLazyNode (newRawMessage (rawJSONObject ))
856
863
857
864
doc .add (part , newNode , options )
858
- doc , err = newNode .intoDoc ()
865
+ doc , err = newNode .intoDoc (options )
859
866
if err != nil {
860
867
return err
861
868
}
@@ -868,7 +875,7 @@ func ensurePathExists(pd *container, path string, options *ApplyOptions) error {
868
875
return err
869
876
}
870
877
} else {
871
- doc , err = target .intoDoc ()
878
+ doc , err = target .intoDoc (options )
872
879
873
880
if err != nil {
874
881
return err
@@ -954,6 +961,8 @@ func (p Patch) replace(doc *container, op Operation, options *ApplyOptions) erro
954
961
if ! val .tryAry () {
955
962
return errors .Wrapf (err , "replace operation value must be object or array" )
956
963
}
964
+ } else {
965
+ val .doc .opts = options
957
966
}
958
967
}
959
968
@@ -1115,7 +1124,7 @@ func (p Patch) copy(doc *container, op Operation, accumulatedCopySize *int64, op
1115
1124
return errors .Wrapf (ErrMissing , "copy operation does not apply: doc is missing destination path: %s" , path )
1116
1125
}
1117
1126
1118
- valCopy , sz , err := deepCopy (val )
1127
+ valCopy , sz , err := deepCopy (val , options )
1119
1128
if err != nil {
1120
1129
return errors .Wrapf (err , "error while performing deep copy" )
1121
1130
}
@@ -1202,6 +1211,7 @@ func (p Patch) ApplyIndentWithOptions(doc []byte, indent string, options *ApplyO
1202
1211
} else {
1203
1212
pd = & partialDoc {
1204
1213
self : self ,
1214
+ opts : options ,
1205
1215
}
1206
1216
}
1207
1217
@@ -1238,11 +1248,18 @@ func (p Patch) ApplyIndentWithOptions(doc []byte, indent string, options *ApplyO
1238
1248
}
1239
1249
}
1240
1250
1241
- if indent != "" {
1242
- return json .MarshalIndent (pd , "" , indent )
1251
+ data , err := json .MarshalEscaped (pd , options .EscapeHTML )
1252
+ if err != nil {
1253
+ return nil , err
1254
+ }
1255
+
1256
+ if indent == "" {
1257
+ return data , nil
1243
1258
}
1244
1259
1245
- return json .Marshal (pd )
1260
+ var buf bytes.Buffer
1261
+ json .Indent (& buf , data , "" , indent )
1262
+ return buf .Bytes (), nil
1246
1263
}
1247
1264
1248
1265
// From http://tools.ietf.org/html/rfc6901#section-4 :
0 commit comments