Skip to content

Commit 98ab5a8

Browse files
canstandreginaldl
andauthored
fix: Evaluate args not serialized correctly (#412)
Co-authored-by: Reginald <[email protected]>
1 parent 0d5814a commit 98ab5a8

File tree

2 files changed

+327
-34
lines changed

2 files changed

+327
-34
lines changed

js_handle.go

Lines changed: 67 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"fmt"
66
"math"
77
"math/big"
8+
"net/url"
89
"reflect"
910
"runtime/debug"
1011
"strings"
@@ -95,13 +96,22 @@ func (j *jsHandleImpl) JSONValue() (interface{}, error) {
9596
}
9697

9798
func parseValue(result interface{}, refs map[float64]interface{}) interface{} {
98-
vMap := result.(map[string]interface{})
99+
vMap, ok := result.(map[string]interface{})
100+
if !ok {
101+
return result
102+
}
99103
if v, ok := vMap["n"]; ok {
100104
if math.Ceil(v.(float64))-v.(float64) == 0 {
101105
return int(v.(float64))
102106
}
103107
return v.(float64)
104108
}
109+
110+
if v, ok := vMap["u"]; ok {
111+
u, _ := url.Parse(v.(string))
112+
return u
113+
}
114+
105115
if v, ok := vMap["bi"]; ok {
106116
n := new(big.Int)
107117
n.SetString(v.(string), 0)
@@ -135,11 +145,12 @@ func parseValue(result interface{}, refs map[float64]interface{}) interface{} {
135145
return math.Inf(-1)
136146
}
137147
if v == "-0" {
138-
return -0
148+
return math.Copysign(0, -1)
139149
}
150+
return v
140151
}
141152
if v, ok := vMap["d"]; ok {
142-
t, _ := time.Parse(time.RFC3339, v.(string))
153+
t, _ := time.Parse(time.RFC3339Nano, v.(string))
143154
return t
144155
}
145156
if v, ok := vMap["a"]; ok {
@@ -152,8 +163,8 @@ func parseValue(result interface{}, refs map[float64]interface{}) interface{} {
152163
}
153164
if v, ok := vMap["o"]; ok {
154165
aV := v.([]interface{})
155-
refs[vMap["id"].(float64)] = v
156166
out := map[string]interface{}{}
167+
refs[vMap["id"].(float64)] = out
157168
for key := range aV {
158169
entry := aV[key].(map[string]interface{})
159170
out[entry["k"].(string)] = parseValue(entry["v"], refs)
@@ -178,6 +189,12 @@ func serializeValue(value interface{}, handles *[]*channel, depth int) interface
178189
"h": h,
179190
}
180191
}
192+
if u, ok := value.(*url.URL); ok {
193+
return map[string]interface{}{
194+
"u": u.String(),
195+
}
196+
}
197+
181198
if depth > 100 {
182199
panic(errors.New("Maximum argument depth exceeded"))
183200
}
@@ -191,8 +208,30 @@ func serializeValue(value interface{}, handles *[]*channel, depth int) interface
191208
"bi": n.String(),
192209
}
193210
}
211+
212+
switch v := value.(type) {
213+
case time.Time:
214+
return map[string]interface{}{
215+
"d": v.Format(time.RFC3339Nano),
216+
}
217+
case int:
218+
return map[string]interface{}{
219+
"n": v,
220+
}
221+
case string:
222+
return map[string]interface{}{
223+
"s": v,
224+
}
225+
case bool:
226+
return map[string]interface{}{
227+
"b": v,
228+
}
229+
}
230+
194231
refV := reflect.ValueOf(value)
195-
if refV.Kind() == reflect.Float32 || refV.Kind() == reflect.Float64 {
232+
233+
switch refV.Kind() {
234+
case reflect.Float32, reflect.Float64:
196235
floatV := refV.Float()
197236
if math.IsInf(floatV, 1) {
198237
return map[string]interface{}{
@@ -204,7 +243,8 @@ func serializeValue(value interface{}, handles *[]*channel, depth int) interface
204243
"v": "-Infinity",
205244
}
206245
}
207-
if floatV == -0 {
246+
// https://github.com/golang/go/issues/2196
247+
if floatV == math.Copysign(0, -1) {
208248
return map[string]interface{}{
209249
"v": "-0",
210250
}
@@ -214,46 +254,39 @@ func serializeValue(value interface{}, handles *[]*channel, depth int) interface
214254
"v": "NaN",
215255
}
216256
}
217-
}
218-
if refV.Kind() == reflect.Slice {
219-
aV := value.([]interface{})
220-
for i := range aV {
221-
aV[i] = serializeValue(aV[i], handles, depth+1)
257+
return map[string]interface{}{
258+
"n": floatV,
222259
}
223-
return aV
224-
}
225-
if refV.Kind() == reflect.Map {
260+
case reflect.Slice:
261+
aV := make([]interface{}, refV.Len())
262+
for i := 0; i < refV.Len(); i++ {
263+
aV[i] = serializeValue(refV.Index(i).Interface(), handles, depth+1)
264+
}
265+
return map[string]interface{}{
266+
"a": aV,
267+
}
268+
case reflect.Map:
226269
out := []interface{}{}
227270
vM := value.(map[string]interface{})
228271
for key := range vM {
272+
v := serializeValue(vM[key], handles, depth+1)
273+
// had key, so convert "undefined" to "null"
274+
if reflect.DeepEqual(v, map[string]interface{}{
275+
"v": "undefined",
276+
}) {
277+
v = map[string]interface{}{
278+
"v": "null",
279+
}
280+
}
229281
out = append(out, map[string]interface{}{
230282
"k": key,
231-
"v": serializeValue(vM[key], handles, depth+1),
283+
"v": v,
232284
})
233285
}
234286
return map[string]interface{}{
235287
"o": out,
236288
}
237289
}
238-
switch v := value.(type) {
239-
case time.Time:
240-
return map[string]interface{}{
241-
"d": v.Format(time.RFC3339) + "Z",
242-
}
243-
case int:
244-
return map[string]interface{}{
245-
"n": v,
246-
}
247-
case string:
248-
return map[string]interface{}{
249-
"s": v,
250-
}
251-
case bool:
252-
return map[string]interface{}{
253-
"b": v,
254-
}
255-
}
256-
257290
return map[string]interface{}{
258291
"v": "undefined",
259292
}

0 commit comments

Comments
 (0)