| 1 | ## oils_failures_allowed: 2
 | 
| 2 | ## tags: dev-minimal
 | 
| 3 | 
 | 
| 4 | #### usage errors
 | 
| 5 | 
 | 
| 6 | json read zz
 | 
| 7 | echo status=$?
 | 
| 8 | 
 | 
| 9 | json write
 | 
| 10 | 
 | 
| 11 | ## status: 3
 | 
| 12 | ## STDOUT:
 | 
| 13 | status=2
 | 
| 14 | ## END
 | 
| 15 | 
 | 
| 16 | #### json write STRING
 | 
| 17 | shopt --set parse_proc
 | 
| 18 | 
 | 
| 19 | json write ('foo')
 | 
| 20 | var s = 'foo'
 | 
| 21 | json write (s)
 | 
| 22 | ## STDOUT:
 | 
| 23 | "foo"
 | 
| 24 | "foo"
 | 
| 25 | ## END
 | 
| 26 | 
 | 
| 27 | #### json write ARRAY
 | 
| 28 | json write (:|foo.cc foo.h|)
 | 
| 29 | json write (['foo.cc', 'foo.h'], space=0)
 | 
| 30 | ## STDOUT:
 | 
| 31 | [
 | 
| 32 |   "foo.cc",
 | 
| 33 |   "foo.h"
 | 
| 34 | ]
 | 
| 35 | ["foo.cc","foo.h"]
 | 
| 36 | ## END
 | 
| 37 | 
 | 
| 38 | #### json write Dict
 | 
| 39 | json write ({k: 'v', k2: [4, 5]})
 | 
| 40 | 
 | 
| 41 | json write ([{k: 'v', k2: 'v2'}, {}])
 | 
| 42 | 
 | 
| 43 | ## STDOUT:
 | 
| 44 | {
 | 
| 45 |   "k": "v",
 | 
| 46 |   "k2": [
 | 
| 47 |     4,
 | 
| 48 |     5
 | 
| 49 |   ]
 | 
| 50 | }
 | 
| 51 | [
 | 
| 52 |   {
 | 
| 53 |     "k": "v",
 | 
| 54 |     "k2": "v2"
 | 
| 55 |   },
 | 
| 56 |   {}
 | 
| 57 | ]
 | 
| 58 | ## END
 | 
| 59 | 
 | 
| 60 | #### json write space=0, space=4
 | 
| 61 | shopt --set parse_proc
 | 
| 62 | 
 | 
| 63 | var mydict = {name: "bob", age: 30}
 | 
| 64 | 
 | 
| 65 | json write (mydict, space=0)
 | 
| 66 | json write (mydict, space=4)
 | 
| 67 | ## STDOUT:
 | 
| 68 | {"name":"bob","age":30}
 | 
| 69 | {
 | 
| 70 |     "name": "bob",
 | 
| 71 |     "age": 30
 | 
| 72 | }
 | 
| 73 | ## END
 | 
| 74 | 
 | 
| 75 | #### json write in command sub
 | 
| 76 | shopt -s oil:all  # for echo
 | 
| 77 | var mydict = {name: "bob", age: 30}
 | 
| 78 | json write (mydict)
 | 
| 79 | var x = $(json write (mydict))
 | 
| 80 | echo $x
 | 
| 81 | ## STDOUT:
 | 
| 82 | {
 | 
| 83 |   "name": "bob",
 | 
| 84 |   "age": 30
 | 
| 85 | }
 | 
| 86 | {
 | 
| 87 |   "name": "bob",
 | 
| 88 |   "age": 30
 | 
| 89 | }
 | 
| 90 | ## END
 | 
| 91 | 
 | 
| 92 | #### json read passed invalid args
 | 
| 93 | 
 | 
| 94 | # EOF
 | 
| 95 | json read
 | 
| 96 | echo status=$?
 | 
| 97 | 
 | 
| 98 | json read 'z z'
 | 
| 99 | echo status=$?
 | 
| 100 | 
 | 
| 101 | json read a b c
 | 
| 102 | echo status=$?
 | 
| 103 | 
 | 
| 104 | ## STDOUT:
 | 
| 105 | status=1
 | 
| 106 | status=2
 | 
| 107 | status=2
 | 
| 108 | ## END
 | 
| 109 | 
 | 
| 110 | #### json read uses $_reply var
 | 
| 111 | 
 | 
| 112 | # space before true
 | 
| 113 | echo ' true' | json read
 | 
| 114 | json write (_reply)
 | 
| 115 | 
 | 
| 116 | ## STDOUT:
 | 
| 117 | true
 | 
| 118 | ## END
 | 
| 119 | 
 | 
| 120 | #### json read then json write
 | 
| 121 | 
 | 
| 122 | # BUG with space before true
 | 
| 123 | echo '{"name": "bob", "age": 42, "ok": true}' | json read
 | 
| 124 | json write (_reply)
 | 
| 125 | 
 | 
| 126 | echo '{"name": "bob", "age": 42, "ok":true}' | json read
 | 
| 127 | json write (_reply)
 | 
| 128 | 
 | 
| 129 | echo '{"name": {}, "age": {}, "x":-1, "y": -0}' | json read
 | 
| 130 | json write (_reply)
 | 
| 131 | 
 | 
| 132 | ## STDOUT:
 | 
| 133 | {
 | 
| 134 |   "name": "bob",
 | 
| 135 |   "age": 42,
 | 
| 136 |   "ok": true
 | 
| 137 | }
 | 
| 138 | {
 | 
| 139 |   "name": "bob",
 | 
| 140 |   "age": 42,
 | 
| 141 |   "ok": true
 | 
| 142 | }
 | 
| 143 | {
 | 
| 144 |   "name": {},
 | 
| 145 |   "age": {},
 | 
| 146 |   "x": -1,
 | 
| 147 |   "y": 0
 | 
| 148 | }
 | 
| 149 | ## END
 | 
| 150 | 
 | 
| 151 | #### json read with redirect
 | 
| 152 | echo '{"age": 42}'  > $TMP/foo.txt
 | 
| 153 | json read (&x) < $TMP/foo.txt
 | 
| 154 | pp cell :x
 | 
| 155 | ## STDOUT:
 | 
| 156 | x = (Cell exported:F readonly:F nameref:F val:(value.Dict d:[Dict age (value.Int i:42)]))
 | 
| 157 | ## END
 | 
| 158 | 
 | 
| 159 | #### json read at end of pipeline (relies on lastpipe)
 | 
| 160 | echo '{"age": 43}' | json read (&y)
 | 
| 161 | pp cell y
 | 
| 162 | ## STDOUT:
 | 
| 163 | y = (Cell exported:F readonly:F nameref:F val:(value.Dict d:[Dict age (value.Int i:43)]))
 | 
| 164 | ## END
 | 
| 165 | 
 | 
| 166 | #### invalid JSON
 | 
| 167 | echo '{' | json read (&y)
 | 
| 168 | echo pipeline status = $?
 | 
| 169 | pp line (y)
 | 
| 170 | ## status: 1
 | 
| 171 | ## STDOUT:
 | 
| 172 | pipeline status = 1
 | 
| 173 | ## END
 | 
| 174 | 
 | 
| 175 | #### Extra data after valid JSON
 | 
| 176 | 
 | 
| 177 | # Trailing space is OK
 | 
| 178 | echo '42  ' | json read
 | 
| 179 | echo num space $?
 | 
| 180 | 
 | 
| 181 | echo '{}  ' | json read
 | 
| 182 | echo obj space $?
 | 
| 183 | 
 | 
| 184 | echo '42 # comment' | json8 read
 | 
| 185 | echo num comment $?
 | 
| 186 | 
 | 
| 187 | echo '{}   # comment ' | json8 read
 | 
| 188 | echo obj comment $?
 | 
| 189 | 
 | 
| 190 | echo '42]' | json read
 | 
| 191 | echo num bracket $?
 | 
| 192 | 
 | 
| 193 | echo '{}]' | json read
 | 
| 194 | echo obj bracket $?
 | 
| 195 | 
 | 
| 196 | ## STDOUT:
 | 
| 197 | num space 0
 | 
| 198 | obj space 0
 | 
| 199 | num comment 0
 | 
| 200 | obj comment 0
 | 
| 201 | num bracket 1
 | 
| 202 | obj bracket 1
 | 
| 203 | ## END
 | 
| 204 | 
 | 
| 205 | #### json write expression
 | 
| 206 | json write ([1,2,3], space=0)
 | 
| 207 | echo status=$?
 | 
| 208 | 
 | 
| 209 | json write (5, 6)  # to many args
 | 
| 210 | echo status=$?
 | 
| 211 | 
 | 
| 212 | ## status: 3
 | 
| 213 | ## STDOUT:
 | 
| 214 | [1,2,3]
 | 
| 215 | status=0
 | 
| 216 | ## END
 | 
| 217 | 
 | 
| 218 | #### json write evaluation error
 | 
| 219 | 
 | 
| 220 | #var block = ^(echo hi)
 | 
| 221 | #json write (block) 
 | 
| 222 | #echo status=$?
 | 
| 223 | 
 | 
| 224 | # undefined var
 | 
| 225 | json write (a) 
 | 
| 226 | echo 'should have failed'
 | 
| 227 | 
 | 
| 228 | ## status: 1
 | 
| 229 | ## STDOUT:
 | 
| 230 | ## END
 | 
| 231 | 
 | 
| 232 | #### json write of List in cycle
 | 
| 233 | 
 | 
| 234 | var L = [1, 2, 3]
 | 
| 235 | setvar L[0] = L
 | 
| 236 | 
 | 
| 237 | shopt -s ysh:upgrade
 | 
| 238 | fopen >tmp.txt {
 | 
| 239 |   pp line (L)
 | 
| 240 | }
 | 
| 241 | fgrep -n -o '[ -->' tmp.txt
 | 
| 242 | 
 | 
| 243 | json write (L)
 | 
| 244 | echo 'should have failed'
 | 
| 245 | 
 | 
| 246 | ## status: 1
 | 
| 247 | ## STDOUT:
 | 
| 248 | 1:[ -->
 | 
| 249 | ## END
 | 
| 250 | 
 | 
| 251 | #### json write of Dict in cycle
 | 
| 252 | 
 | 
| 253 | var d = {}
 | 
| 254 | setvar d.k = d
 | 
| 255 | 
 | 
| 256 | shopt -s ysh:upgrade
 | 
| 257 | fopen >tmp.txt {
 | 
| 258 |   pp line (d)
 | 
| 259 | }
 | 
| 260 | fgrep -n -o '{ -->' tmp.txt
 | 
| 261 | 
 | 
| 262 | json write (d)
 | 
| 263 | echo 'should have failed'
 | 
| 264 | 
 | 
| 265 | ## status: 1
 | 
| 266 | ## STDOUT:
 | 
| 267 | 1:{ -->
 | 
| 268 | ## END
 | 
| 269 | 
 | 
| 270 | #### json write of List/Dict referenced twice (bug fix)
 | 
| 271 | 
 | 
| 272 | var mylist = [1,2,3]
 | 
| 273 | var mydict = {foo: "bar"}
 | 
| 274 | 
 | 
| 275 | var top = {k: mylist, k2: mylist, k3: mydict, k4: mydict}
 | 
| 276 | 
 | 
| 277 | # BUG!
 | 
| 278 | json write (top, space=0)
 | 
| 279 | 
 | 
| 280 | ## STDOUT:
 | 
| 281 | {"k":[1,2,3],"k2":[1,2,3],"k3":{"foo":"bar"},"k4":{"foo":"bar"}}
 | 
| 282 | ## END
 | 
| 283 | 
 | 
| 284 | #### json read doesn't accept u'' or b'' strings
 | 
| 285 | 
 | 
| 286 | json read <<EOF
 | 
| 287 | {"key": u'val'}
 | 
| 288 | EOF
 | 
| 289 | echo status=$?
 | 
| 290 | 
 | 
| 291 | #pp line (_reply)
 | 
| 292 | 
 | 
| 293 | json read <<EOF
 | 
| 294 | {"key": b'val'}
 | 
| 295 | EOF
 | 
| 296 | echo status=$?
 | 
| 297 | 
 | 
| 298 | ## STDOUT:
 | 
| 299 | status=1
 | 
| 300 | status=1
 | 
| 301 | ## END
 | 
| 302 | 
 | 
| 303 | #### json read doesn't accept comments, but json8 does
 | 
| 304 | 
 | 
| 305 | json8 read <<EOF
 | 
| 306 | {  # comment
 | 
| 307 |   "key":  # zz
 | 
| 308 |   b'val',  # yy
 | 
| 309 |   "k2": "v2"  #
 | 
| 310 | }
 | 
| 311 | EOF
 | 
| 312 | echo status=$?
 | 
| 313 | 
 | 
| 314 | json8 write (_reply)
 | 
| 315 | 
 | 
| 316 | json read <<EOF
 | 
| 317 | {"key": "val"}  # comment
 | 
| 318 | EOF
 | 
| 319 | echo status=$?
 | 
| 320 | ## STDOUT:
 | 
| 321 | status=0
 | 
| 322 | {
 | 
| 323 |   "key": "val",
 | 
| 324 |   "k2": "v2"
 | 
| 325 | }
 | 
| 326 | status=1
 | 
| 327 | ## END
 | 
| 328 | 
 | 
| 329 | 
 | 
| 330 | #### json write emits Unicode replacement char for binary data \yff
 | 
| 331 | 
 | 
| 332 | json write ([3, "foo", $'-\xff\xfe---\xfd=']) > tmp.txt
 | 
| 333 | 
 | 
| 334 | # Round trip it for good measure
 | 
| 335 | json read < tmp.txt
 | 
| 336 | 
 | 
| 337 | json write (_reply)
 | 
| 338 | 
 | 
| 339 | ## STDOUT:
 | 
| 340 | [
 | 
| 341 |   3,
 | 
| 342 |   "foo",
 | 
| 343 |   "-��---�="
 | 
| 344 | ]
 | 
| 345 | ## END
 | 
| 346 | 
 | 
| 347 | #### json8 accepts j"" prefix, but json doesn't
 | 
| 348 | 
 | 
| 349 | var msg = r'j"foo\nbar"'
 | 
| 350 | 
 | 
| 351 | echo "$msg" | json read
 | 
| 352 | echo json=$?
 | 
| 353 | echo
 | 
| 354 | 
 | 
| 355 | echo "$msg" | json8 read
 | 
| 356 | echo json8=$?
 | 
| 357 | pp line (_reply)
 | 
| 358 | echo
 | 
| 359 | 
 | 
| 360 | var msg = r'j"\u0041"'
 | 
| 361 | echo "$msg" | json8 read
 | 
| 362 | echo json8=$?
 | 
| 363 | pp line (_reply)
 | 
| 364 | 
 | 
| 365 | 
 | 
| 366 | ## STDOUT:
 | 
| 367 | json=1
 | 
| 368 | 
 | 
| 369 | json8=0
 | 
| 370 | (Str)   "foo\nbar"
 | 
| 371 | 
 | 
| 372 | json8=0
 | 
| 373 | (Str)   "A"
 | 
| 374 | ## END
 | 
| 375 | 
 | 
| 376 | #### j"" prefix not accepted in YSH (could be added later)
 | 
| 377 | 
 | 
| 378 | shopt -s ysh:all
 | 
| 379 | 
 | 
| 380 | # denied by YSH
 | 
| 381 | # echo j"\u{7f}"
 | 
| 382 | 
 | 
| 383 | var s = j"\u{7f}"
 | 
| 384 | 
 | 
| 385 | ## status: 2
 | 
| 386 | ## STDOUT:
 | 
| 387 | ## END
 | 
| 388 | 
 | 
| 389 | 
 | 
| 390 | #### json8 write emits b'' strings for binary data \yff
 | 
| 391 | 
 | 
| 392 | json8 write ([3, "foo", $'-\xff\xfe-\xfd='])
 | 
| 393 | 
 | 
| 394 | ## STDOUT:
 | 
| 395 | [
 | 
| 396 |   3,
 | 
| 397 |   "foo",
 | 
| 398 |   b'-\yff\yfe-\yfd='
 | 
| 399 | ]
 | 
| 400 | ## END
 | 
| 401 | 
 | 
| 402 | 
 | 
| 403 | #### json8 write bytes vs unicode string
 | 
| 404 | 
 | 
| 405 | u=$'mu \u03bc \x01 \" \\ \b\f\n\r\t'
 | 
| 406 | u2=$'\x01\x1f'  # this is a valid unicode string
 | 
| 407 | 
 | 
| 408 | b=$'\xff'  # this isn't valid unicode
 | 
| 409 | 
 | 
| 410 | json8 write (u)
 | 
| 411 | json8 write (u2)
 | 
| 412 | 
 | 
| 413 | json8 write (b)
 | 
| 414 | 
 | 
| 415 | ## STDOUT:
 | 
| 416 | "mu μ \u0001 \" \\ \b\f\n\r\t"
 | 
| 417 | "\u0001\u001f"
 | 
| 418 | b'\yff'
 | 
| 419 | ## END
 | 
| 420 | 
 | 
| 421 | #### JSON \/ escapes supported
 | 
| 422 | 
 | 
| 423 | msg='"\/"'
 | 
| 424 | 
 | 
| 425 | echo "$msg" | python3 -c 'import json, sys; print(json.load(sys.stdin))'
 | 
| 426 | 
 | 
| 427 | echo "$msg" | json read
 | 
| 428 | echo reply=$_reply
 | 
| 429 | 
 | 
| 430 | j8="b'\\/'"
 | 
| 431 | echo "$msg" | json read
 | 
| 432 | echo reply=$_reply
 | 
| 433 | 
 | 
| 434 | 
 | 
| 435 | ## STDOUT:
 | 
| 436 | /
 | 
| 437 | reply=/
 | 
| 438 | reply=/
 | 
| 439 | ## END
 | 
| 440 | 
 | 
| 441 | #### JSON string can have unescaped ' and J8 string can have unescaped "
 | 
| 442 | 
 | 
| 443 | json read <<EOF
 | 
| 444 | "'"
 | 
| 445 | EOF
 | 
| 446 | 
 | 
| 447 | pp line (_reply)
 | 
| 448 | 
 | 
| 449 | json8 read <<EOF
 | 
| 450 | u'"'
 | 
| 451 | EOF
 | 
| 452 | 
 | 
| 453 | pp line (_reply)
 | 
| 454 | 
 | 
| 455 | ## STDOUT:
 | 
| 456 | (Str)   "'"
 | 
| 457 | (Str)   "\""
 | 
| 458 | ## END
 | 
| 459 | 
 | 
| 460 | 
 | 
| 461 | #### J8 supports superfluous \" escapes, but JSON doesn't support \' escapes
 | 
| 462 | 
 | 
| 463 | json8 read <<'EOF'
 | 
| 464 | b'\"'
 | 
| 465 | EOF
 | 
| 466 | echo reply=$_reply
 | 
| 467 | 
 | 
| 468 | json8 read <<'EOF'
 | 
| 469 | b'\'\'\b\f\n\r\t\"\\'
 | 
| 470 | EOF
 | 
| 471 | pp line (_reply)
 | 
| 472 | 
 | 
| 473 | # Suppress traceback
 | 
| 474 | python3 -c 'import json, sys; print(json.load(sys.stdin))' 2>/dev/null <<'EOF'
 | 
| 475 | "\'"
 | 
| 476 | EOF
 | 
| 477 | echo python3=$?
 | 
| 478 | 
 | 
| 479 | json read <<'EOF'
 | 
| 480 | "\'"
 | 
| 481 | EOF
 | 
| 482 | echo json=$?
 | 
| 483 | 
 | 
| 484 | ## STDOUT:
 | 
| 485 | reply="
 | 
| 486 | (Str)   "''\b\f\n\r\t\"\\"
 | 
| 487 | python3=1
 | 
| 488 | json=1
 | 
| 489 | ## END
 | 
| 490 | 
 | 
| 491 | #### Escaping uses \u0001 in "", but \u{1} in b''
 | 
| 492 | 
 | 
| 493 | s1=$'\x01'
 | 
| 494 | s2=$'\x01\xff\x1f'  # byte string
 | 
| 495 | 
 | 
| 496 | json8 write (s1)
 | 
| 497 | json8 write (s2)
 | 
| 498 | 
 | 
| 499 | ## STDOUT:
 | 
| 500 | "\u0001"
 | 
| 501 | b'\u{1}\yff\u{1f}'
 | 
| 502 | ## END
 | 
| 503 | 
 | 
| 504 | 
 | 
| 505 | #### json8 read
 | 
| 506 | 
 | 
| 507 | echo '{ }' | json8 read
 | 
| 508 | pp line (_reply)
 | 
| 509 | 
 | 
| 510 | echo '[ ]' | json8 read
 | 
| 511 | pp line (_reply)
 | 
| 512 | 
 | 
| 513 | echo '[42]' | json8 read
 | 
| 514 | pp line (_reply)
 | 
| 515 | 
 | 
| 516 | echo '[true, false]' | json8 read
 | 
| 517 | pp line (_reply)
 | 
| 518 | 
 | 
| 519 | echo '{"k": "v"}' | json8 read
 | 
| 520 | pp line (_reply)
 | 
| 521 | 
 | 
| 522 | echo '{"k": null}' | json8 read
 | 
| 523 | pp line (_reply)
 | 
| 524 | 
 | 
| 525 | echo '{"k": 1, "k2": 2}' | json8 read
 | 
| 526 | pp line (_reply)
 | 
| 527 | 
 | 
| 528 | echo "{u'k': {b'k2': null}}" | json8 read
 | 
| 529 | pp line (_reply)
 | 
| 530 | 
 | 
| 531 | echo '{"k": {"k2": "v2"}, "k3": "backslash \\ \" \n line 2 \u03bc "}' | json8 read
 | 
| 532 | pp line (_reply)
 | 
| 533 | 
 | 
| 534 | json8 read (&x) <<'EOF'
 | 
| 535 | {u'k': {u'k2': u'v2'}, u'k3': u'backslash \\ \" \n line 2 \u{3bc} '}
 | 
| 536 | EOF
 | 
| 537 | pp line (x)
 | 
| 538 | 
 | 
| 539 | ## STDOUT:
 | 
| 540 | (Dict)   {}
 | 
| 541 | (List)   []
 | 
| 542 | (List)   [42]
 | 
| 543 | (List)   [true,false]
 | 
| 544 | (Dict)   {"k":"v"}
 | 
| 545 | (Dict)   {"k":null}
 | 
| 546 | (Dict)   {"k":1,"k2":2}
 | 
| 547 | (Dict)   {"k":{"k2":null}}
 | 
| 548 | (Dict)   {"k":{"k2":"v2"},"k3":"backslash \\ \" \n line 2 μ "}
 | 
| 549 | (Dict)   {"k":{"k2":"v2"},"k3":"backslash \\ \" \n line 2 μ "}
 | 
| 550 | ## END
 | 
| 551 | 
 | 
| 552 | #### json8 round trip
 | 
| 553 | 
 | 
| 554 | var obj = [42, 1.5, null, true, "hi", b'\yff\yfe\b\n""']
 | 
| 555 | 
 | 
| 556 | json8 write (obj, space=0) > j
 | 
| 557 | 
 | 
| 558 | cat j
 | 
| 559 | 
 | 
| 560 | json8 read < j
 | 
| 561 | 
 | 
| 562 | json8 write (_reply)
 | 
| 563 | 
 | 
| 564 | ## STDOUT:
 | 
| 565 | [42,1.5,null,true,"hi",b'\yff\yfe\b\n""']
 | 
| 566 | [
 | 
| 567 |   42,
 | 
| 568 |   1.5,
 | 
| 569 |   null,
 | 
| 570 |   true,
 | 
| 571 |   "hi",
 | 
| 572 |   b'\yff\yfe\b\n""'
 | 
| 573 | ]
 | 
| 574 | ## END
 | 
| 575 | 
 | 
| 576 | #### json round trip (regression)
 | 
| 577 | 
 | 
| 578 | var d = {
 | 
| 579 |   short: '-v', long: '--verbose', type: null, default: '', help: 'Enable verbose logging'
 | 
| 580 | }
 | 
| 581 | 
 | 
| 582 | json write (d) | json read
 | 
| 583 | 
 | 
| 584 | pp line (_reply)
 | 
| 585 | 
 | 
| 586 | ## STDOUT:
 | 
| 587 | (Dict)   {"short":"-v","long":"--verbose","type":null,"default":"","help":"Enable verbose logging"}
 | 
| 588 | ## END
 | 
| 589 | 
 | 
| 590 | #### round trip: decode surrogate pair and encode
 | 
| 591 | 
 | 
| 592 | var j = r'"\ud83e\udd26"'
 | 
| 593 | echo $j | json read (&c1)
 | 
| 594 | 
 | 
| 595 | json write (c1)
 | 
| 596 | 
 | 
| 597 | var j = r'"\uD83E\uDD26"'
 | 
| 598 | echo $j | json read (&c2)
 | 
| 599 | 
 | 
| 600 | json write (c2)
 | 
| 601 | 
 | 
| 602 | # Not a surrogate pair
 | 
| 603 | var j = r'"\u0001\u0002"' 
 | 
| 604 | echo $j | json read (&c3)
 | 
| 605 | 
 | 
| 606 | json write (c3)
 | 
| 607 | 
 | 
| 608 | var j = r'"\u0100\u0101\u0102"' 
 | 
| 609 | echo $j | json read (&c4)
 | 
| 610 | 
 | 
| 611 | json write (c4)
 | 
| 612 | 
 | 
| 613 | ## STDOUT:
 | 
| 614 | "🤦"
 | 
| 615 | "🤦"
 | 
| 616 | "\u0001\u0002"
 | 
| 617 | "ĀāĂ"
 | 
| 618 | ## END
 | 
| 619 | 
 | 
| 620 | #### round trip: decode surrogate half and encode
 | 
| 621 | 
 | 
| 622 | shopt -s ysh:upgrade
 | 
| 623 | 
 | 
| 624 | for j in '"\ud83e"' '"\udd26"' {
 | 
| 625 |   var s = fromJson(j)
 | 
| 626 |   write -- "$j"
 | 
| 627 |   pp line (s)
 | 
| 628 | 
 | 
| 629 |   write -n 'json ';  json write (s)
 | 
| 630 | 
 | 
| 631 |   write -n 'json8 '; json8 write (s)
 | 
| 632 | 
 | 
| 633 |   echo
 | 
| 634 | }
 | 
| 635 | 
 | 
| 636 | ## STDOUT:
 | 
| 637 | "\ud83e"
 | 
| 638 | (Str)   b'\yed\ya0\ybe'
 | 
| 639 | json "\ud83e"
 | 
| 640 | json8 b'\yed\ya0\ybe'
 | 
| 641 | 
 | 
| 642 | "\udd26"
 | 
| 643 | (Str)   b'\yed\yb4\ya6'
 | 
| 644 | json "\udd26"
 | 
| 645 | json8 b'\yed\yb4\ya6'
 | 
| 646 | 
 | 
| 647 | ## END
 | 
| 648 | 
 | 
| 649 | #### toJson() toJson8()
 | 
| 650 | 
 | 
| 651 | var obj = [42, 1.5, null, true, "hi", b'\yf0']
 | 
| 652 | 
 | 
| 653 | echo $[toJson(obj)]
 | 
| 654 | echo $[toJson8(obj)]
 | 
| 655 | 
 | 
| 656 | var obj2 = [3, 4]
 | 
| 657 | echo $[toJson(obj2, space=0)]  # same as the default
 | 
| 658 | echo $[toJson8(obj2, space=0)]
 | 
| 659 | 
 | 
| 660 | echo $[toJson(obj2, space=2)]
 | 
| 661 | echo $[toJson8(obj2, space=2)]
 | 
| 662 | 
 | 
| 663 | # fully specify this behavior
 | 
| 664 | echo $[toJson(obj2, space=-2)]
 | 
| 665 | echo $[toJson8(obj2, space=-2)]
 | 
| 666 | 
 | 
| 667 | ## STDOUT:
 | 
| 668 | [42,1.5,null,true,"hi","�"]
 | 
| 669 | [42,1.5,null,true,"hi",b'\yf0']
 | 
| 670 | [3,4]
 | 
| 671 | [3,4]
 | 
| 672 | [
 | 
| 673 |   3,
 | 
| 674 |   4
 | 
| 675 | ]
 | 
| 676 | [
 | 
| 677 |   3,
 | 
| 678 |   4
 | 
| 679 | ]
 | 
| 680 | [3,4]
 | 
| 681 | [3,4]
 | 
| 682 | ## END
 | 
| 683 | 
 | 
| 684 | #### fromJson() fromJson8()
 | 
| 685 | 
 | 
| 686 | var m1 = '[42,1.5,null,true,"hi"]'
 | 
| 687 | 
 | 
| 688 | # JSON8 message
 | 
| 689 | var m2 = '[42,1.5,null,true,"hi",' ++ "u''" ++ ']'
 | 
| 690 | 
 | 
| 691 | pp line (fromJson8(m1))
 | 
| 692 | pp line (fromJson(m1))
 | 
| 693 | 
 | 
| 694 | pp line (fromJson8(m2))
 | 
| 695 | pp line (fromJson(m2))  # fails
 | 
| 696 | 
 | 
| 697 | ## status: 4
 | 
| 698 | ## STDOUT:
 | 
| 699 | (List)   [42,1.5,null,true,"hi"]
 | 
| 700 | (List)   [42,1.5,null,true,"hi"]
 | 
| 701 | (List)   [42,1.5,null,true,"hi",""]
 | 
| 702 | ## END
 | 
| 703 | 
 | 
| 704 | #### User can handle errors - toJson() toJson8()
 | 
| 705 | shopt -s ysh:upgrade
 | 
| 706 | 
 | 
| 707 | var obj = []
 | 
| 708 | call obj->append(obj)
 | 
| 709 | 
 | 
| 710 | try {
 | 
| 711 |   echo $[toJson(obj)]
 | 
| 712 | }
 | 
| 713 | echo status=$_status
 | 
| 714 | echo "encode error $[_error.message]" | sed 's/0x[a-f0-9]\+/(object id)/'
 | 
| 715 | 
 | 
| 716 | try {  # use different style
 | 
| 717 |   echo $[toJson8( /d+/ )]
 | 
| 718 | }
 | 
| 719 | echo status=$_status
 | 
| 720 | echo "encode error $[_error.message]"
 | 
| 721 | 
 | 
| 722 | # This makes the interpreter fail with a message
 | 
| 723 | echo $[toJson(obj)]
 | 
| 724 | 
 | 
| 725 | ## status: 4
 | 
| 726 | ## STDOUT:
 | 
| 727 | status=4
 | 
| 728 | encode error Can't encode List (object id) in object cycle
 | 
| 729 | status=4
 | 
| 730 | encode error Can't serialize object of type Eggex
 | 
| 731 | ## END
 | 
| 732 | 
 | 
| 733 | #### User can handle errors - fromJson() fromJson8()
 | 
| 734 | shopt -s ysh:upgrade
 | 
| 735 | 
 | 
| 736 | var message ='[42,1.5,null,true,"hi"'
 | 
| 737 | 
 | 
| 738 | try {
 | 
| 739 |   var obj = fromJson(message)
 | 
| 740 | }
 | 
| 741 | echo status=$_status
 | 
| 742 | echo "decode error $[_error.message]" | egrep -o '.*Expected.*RBracket'
 | 
| 743 | 
 | 
| 744 | try {
 | 
| 745 |   var obj = fromJson8(message)
 | 
| 746 | }
 | 
| 747 | echo status=$_status
 | 
| 748 | echo "decode error $[_error.message]" | egrep -o '.*Expected.*RBracket'
 | 
| 749 | 
 | 
| 750 | try {
 | 
| 751 |   var obj = fromJson('[+]')
 | 
| 752 | }
 | 
| 753 | echo "positions $[_error.start_pos] - $[_error.end_pos]"
 | 
| 754 | 
 | 
| 755 | # This makes the interpreter fail with a message
 | 
| 756 | var obj = fromJson(message)
 | 
| 757 | 
 | 
| 758 | ## status: 4
 | 
| 759 | ## STDOUT:
 | 
| 760 | status=4
 | 
| 761 | decode error Expected Id.J8_RBracket
 | 
| 762 | status=4
 | 
| 763 | decode error Expected Id.J8_RBracket
 | 
| 764 | positions 1 - 2
 | 
| 765 | ## END
 | 
| 766 | 
 | 
| 767 | 
 | 
| 768 | #### ASCII control chars can't appear literally in messages
 | 
| 769 | shopt -s ysh:upgrade
 | 
| 770 | 
 | 
| 771 | var message=$'"\x01"'
 | 
| 772 | #echo $message | od -c
 | 
| 773 | 
 | 
| 774 | try {
 | 
| 775 |   var obj = fromJson(message)
 | 
| 776 | }
 | 
| 777 | echo status=$_status
 | 
| 778 | echo "$[_error.message]" | egrep -o 'ASCII control chars'
 | 
| 779 | 
 | 
| 780 | ## STDOUT:
 | 
| 781 | status=4
 | 
| 782 | ASCII control chars
 | 
| 783 | ## END
 | 
| 784 | 
 | 
| 785 | 
 | 
| 786 | #### \yff can't appear in u'' code strings (command)
 | 
| 787 | 
 | 
| 788 | shopt -s ysh:upgrade
 | 
| 789 | 
 | 
| 790 | echo -n b'\yfd' | od -A n -t x1
 | 
| 791 | echo -n u'\yfd' | od -A n -t x1
 | 
| 792 | 
 | 
| 793 | ## status: 2
 | 
| 794 | ## STDOUT:
 | 
| 795 |  fd
 | 
| 796 | ## END
 | 
| 797 | 
 | 
| 798 | #### \yff can't appear in u'' code strings (expr)
 | 
| 799 | 
 | 
| 800 | var x = b'\yfe' 
 | 
| 801 | write -n -- $x | od -A n -t x1
 | 
| 802 | 
 | 
| 803 | var x = u'\yfe' 
 | 
| 804 | write -n -- $x | od -A n -t x1
 | 
| 805 | 
 | 
| 806 | ## status: 2
 | 
| 807 | ## STDOUT:
 | 
| 808 |  fe
 | 
| 809 | ## END
 | 
| 810 | 
 | 
| 811 | #### \yff can't appear in u'' multiline code strings
 | 
| 812 | 
 | 
| 813 | shopt -s ysh:upgrade
 | 
| 814 | 
 | 
| 815 | echo -n b'''\yfc''' | od -A n -t x1
 | 
| 816 | echo -n u'''\yfd''' | od -A n -t x1
 | 
| 817 | 
 | 
| 818 | ## status: 2
 | 
| 819 | ## STDOUT:
 | 
| 820 |  fc
 | 
| 821 | ## END
 | 
| 822 | 
 | 
| 823 | #### \yff can't appear in u'' data strings
 | 
| 824 | 
 | 
| 825 | #shopt -s ysh:upgrade
 | 
| 826 | 
 | 
| 827 | json8 read (&b) <<'EOF'
 | 
| 828 | b'\yfe'
 | 
| 829 | EOF
 | 
| 830 | pp line (b)
 | 
| 831 | 
 | 
| 832 | json8 read (&u) <<'EOF'
 | 
| 833 | u'\yfe'
 | 
| 834 | EOF
 | 
| 835 | pp line (u)  # undefined
 | 
| 836 | 
 | 
| 837 | ## status: 1
 | 
| 838 | ## STDOUT:
 | 
| 839 | (Str)   b'\yfe'
 | 
| 840 | ## END
 | 
| 841 | 
 | 
| 842 | #### \u{dc00} can't be in surrogate range in code (command)
 | 
| 843 | 
 | 
| 844 | shopt -s ysh:upgrade
 | 
| 845 | 
 | 
| 846 | echo -n u'\u{dc00}' | od -A n -t x1
 | 
| 847 | 
 | 
| 848 | ## status: 2
 | 
| 849 | ## STDOUT:
 | 
| 850 | ## END
 | 
| 851 | 
 | 
| 852 | #### \u{dc00} can't be in surrogate range in code (expr)
 | 
| 853 | 
 | 
| 854 | shopt -s ysh:upgrade
 | 
| 855 | 
 | 
| 856 | var x = u'\u{dc00}' 
 | 
| 857 | echo $x | od -A n -t x1
 | 
| 858 | 
 | 
| 859 | ## status: 2
 | 
| 860 | ## STDOUT:
 | 
| 861 | ## END
 | 
| 862 | 
 | 
| 863 | #### \u{dc00} can't be in surrogate range in data
 | 
| 864 | 
 | 
| 865 | json8 read <<'EOF'
 | 
| 866 | ["long string", u'hello \u{d7ff}', "other"]
 | 
| 867 | EOF
 | 
| 868 | echo status=$?
 | 
| 869 | 
 | 
| 870 | json8 read <<'EOF'
 | 
| 871 | ["long string", u'hello \u{d800}', "other"]
 | 
| 872 | EOF
 | 
| 873 | echo status=$?
 | 
| 874 | 
 | 
| 875 | json8 read <<'EOF'
 | 
| 876 | ["long string", u'hello \u{dfff}', "other"]
 | 
| 877 | EOF
 | 
| 878 | echo status=$?
 | 
| 879 | 
 | 
| 880 | json8 read <<'EOF'
 | 
| 881 | ["long string", u'hello \u{e000}', "other"]
 | 
| 882 | EOF
 | 
| 883 | echo status=$?
 | 
| 884 | 
 | 
| 885 | 
 | 
| 886 | ## STDOUT:
 | 
| 887 | status=0
 | 
| 888 | status=1
 | 
| 889 | status=1
 | 
| 890 | status=0
 | 
| 891 | ## END
 | 
| 892 | 
 | 
| 893 | 
 | 
| 894 | #### Inf is encoded as null, like JavaScript
 | 
| 895 | 
 | 
| 896 | # WRONG LOCATION!  Gah
 | 
| 897 | #var x = fromJson(repeat('123', 20))
 | 
| 898 | 
 | 
| 899 | shopt --set ysh:upgrade
 | 
| 900 | 
 | 
| 901 | source $LIB_YSH/list.ysh
 | 
| 902 | 
 | 
| 903 | # Create inf
 | 
| 904 | var big = repeat('12345678', 100) ++ '.0'
 | 
| 905 | #pp line (s)
 | 
| 906 | var inf = fromJson(big)
 | 
| 907 | var neg_inf = fromJson('-' ++ big)
 | 
| 908 | 
 | 
| 909 | # Can be printed
 | 
| 910 | pp line (inf)
 | 
| 911 | pp line (neg_inf)
 | 
| 912 | echo --
 | 
| 913 | 
 | 
| 914 | # Can't be serialized
 | 
| 915 | try {
 | 
| 916 |   json write (inf)
 | 
| 917 | }
 | 
| 918 | echo error=$[_error.code]
 | 
| 919 | 
 | 
| 920 | try {
 | 
| 921 |   json write (neg_inf)
 | 
| 922 | }
 | 
| 923 | echo error=$[_error.code]
 | 
| 924 | 
 | 
| 925 | echo --
 | 
| 926 | echo $[toJson(inf)]
 | 
| 927 | echo $[toJson(neg_inf)]
 | 
| 928 | 
 | 
| 929 | ## STDOUT:
 | 
| 930 | (Float)   inf
 | 
| 931 | (Float)   -inf
 | 
| 932 | --
 | 
| 933 | null
 | 
| 934 | error=0
 | 
| 935 | null
 | 
| 936 | error=0
 | 
| 937 | --
 | 
| 938 | null
 | 
| 939 | null
 | 
| 940 | ## END
 | 
| 941 | 
 | 
| 942 | #### NaN is encoded as null, like JavaScript
 | 
| 943 | 
 | 
| 944 | pp line (NAN)
 | 
| 945 | 
 | 
| 946 | json write (NAN)
 | 
| 947 | 
 | 
| 948 | echo $[toJson(NAN)]
 | 
| 949 | 
 | 
| 950 | ## STDOUT:
 | 
| 951 | (Float)   nan
 | 
| 952 | null
 | 
| 953 | null
 | 
| 954 | ## END
 | 
| 955 | 
 | 
| 956 | 
 | 
| 957 | #### Invalid UTF-8 in JSON is rejected
 | 
| 958 | 
 | 
| 959 | echo $'"\xff"' | json read
 | 
| 960 | echo status=$?
 | 
| 961 | 
 | 
| 962 | echo $'"\xff"' | json8 read
 | 
| 963 | echo status=$?
 | 
| 964 | 
 | 
| 965 | echo $'\xff' | json read
 | 
| 966 | echo status=$?
 | 
| 967 | 
 | 
| 968 | echo $'\xff' | json8 read
 | 
| 969 | echo status=$?
 | 
| 970 | 
 | 
| 971 | ## STDOUT:
 | 
| 972 | status=1
 | 
| 973 | status=1
 | 
| 974 | status=1
 | 
| 975 | status=1
 | 
| 976 | ## END
 | 
| 977 | 
 | 
| 978 | #### Invalid JSON in J8 is rejected
 | 
| 979 | 
 | 
| 980 | json8 read <<EOF
 | 
| 981 | b'$(echo -e -n '\xff')'
 | 
| 982 | EOF
 | 
| 983 | echo status=$?
 | 
| 984 | 
 | 
| 985 | json8 read <<EOF
 | 
| 986 | u'$(echo -e -n '\xff')'
 | 
| 987 | EOF
 | 
| 988 | echo status=$?
 | 
| 989 | 
 | 
| 990 | ## STDOUT:
 | 
| 991 | status=1
 | 
| 992 | status=1
 | 
| 993 | ## END
 | 
| 994 | 
 | 
| 995 | #### '' means the same thing as u''
 | 
| 996 | 
 | 
| 997 | echo "''" | json8 read
 | 
| 998 | pp line (_reply)
 | 
| 999 | 
 | 
| 1000 | echo "'\u{3bc}'" | json8 read
 | 
| 1001 | pp line (_reply)
 | 
| 1002 | 
 | 
| 1003 | echo "'\yff'" | json8 read
 | 
| 1004 | echo status=$?
 | 
| 1005 | 
 | 
| 1006 | ## STDOUT:
 | 
| 1007 | (Str)   ""
 | 
| 1008 | (Str)   "μ"
 | 
| 1009 | status=1
 | 
| 1010 | ## END
 | 
| 1011 | 
 | 
| 1012 | #### decode integer larger than 2^32
 | 
| 1013 | 
 | 
| 1014 | json=$(( 1 << 33 ))
 | 
| 1015 | echo $json
 | 
| 1016 | 
 | 
| 1017 | echo $json | json read
 | 
| 1018 | pp line (_reply)
 | 
| 1019 | 
 | 
| 1020 | ## STDOUT:
 | 
| 1021 | 8589934592
 | 
| 1022 | (Int)   8589934592
 | 
| 1023 | ## END
 | 
| 1024 | 
 | 
| 1025 | #### decode integer larger than 2^64
 | 
| 1026 | 
 | 
| 1027 | $SH <<'EOF'
 | 
| 1028 | json read <<< '123456789123456789123456789'
 | 
| 1029 | echo status=$?
 | 
| 1030 | pp line (_reply)
 | 
| 1031 | EOF
 | 
| 1032 | 
 | 
| 1033 | $SH <<'EOF'
 | 
| 1034 | json read <<< '-123456789123456789123456789'
 | 
| 1035 | echo status=$?
 | 
| 1036 | pp line (_reply)
 | 
| 1037 | EOF
 | 
| 1038 | 
 | 
| 1039 | echo ok
 | 
| 1040 | 
 | 
| 1041 | ## STDOUT:
 | 
| 1042 | status=1
 | 
| 1043 | status=1
 | 
| 1044 | ok
 | 
| 1045 | ## END
 | 
| 1046 | 
 | 
| 1047 | 
 | 
| 1048 | #### round trip: read/write with ysh
 | 
| 1049 | 
 | 
| 1050 | var file = "$REPO_ROOT/spec/testdata/bug.json"
 | 
| 1051 | #cat $file
 | 
| 1052 | cat $file | json read (&cfg)
 | 
| 1053 | json write (cfg) > ysh-json
 | 
| 1054 | 
 | 
| 1055 | diff -u $file ysh-json
 | 
| 1056 | echo diff=$?
 | 
| 1057 | 
 | 
| 1058 | ## STDOUT:
 | 
| 1059 | diff=0
 | 
| 1060 | ## END
 | 
| 1061 | 
 | 
| 1062 | #### round trip: read/write with ysh, read/write with Python 3 (bug regression)
 | 
| 1063 | 
 | 
| 1064 | var file = "$REPO_ROOT/spec/testdata/bug.json"
 | 
| 1065 | #cat $file
 | 
| 1066 | cat $file | json read (&cfg)
 | 
| 1067 | json write (cfg) > ysh-json
 | 
| 1068 | 
 | 
| 1069 | cat ysh-json | python3 -c \
 | 
| 1070 |   'import json, sys; obj = json.load(sys.stdin); json.dump(obj, sys.stdout, indent=2); print()' \
 | 
| 1071 |   > py-json
 | 
| 1072 | 
 | 
| 1073 | diff -u $file py-json
 | 
| 1074 | echo diff=$?
 | 
| 1075 | 
 | 
| 1076 | ## STDOUT:
 | 
| 1077 | diff=0
 | 
| 1078 | ## END
 | 
| 1079 | 
 | 
| 1080 | #### Encoding bytes that don't hit UTF8_REJECT immediately (bug fix)
 | 
| 1081 | 
 | 
| 1082 | var x = $'\xce'
 | 
| 1083 | json8 write (x)
 | 
| 1084 | declare -p x
 | 
| 1085 | echo
 | 
| 1086 | 
 | 
| 1087 | var y = $'\xbc'
 | 
| 1088 | json8 write (y)
 | 
| 1089 | declare -p y
 | 
| 1090 | echo
 | 
| 1091 | 
 | 
| 1092 | var z = $'\xf0\x9f\xa4\xff'
 | 
| 1093 | json8 write (z)
 | 
| 1094 | declare -p z
 | 
| 1095 | 
 | 
| 1096 | ## STDOUT:
 | 
| 1097 | b'\yce'
 | 
| 1098 | declare -- x=$'\xce'
 | 
| 1099 | 
 | 
| 1100 | b'\ybc'
 | 
| 1101 | declare -- y=$'\xbc'
 | 
| 1102 | 
 | 
| 1103 | b'\yf0\y9f\ya4\yff'
 | 
| 1104 | declare -- z=$'\xf0\x9f\xa4\xff'
 | 
| 1105 | ## END
 | 
| 1106 | 
 | 
| 1107 | #### NIL8 token in JSON / JSON8
 | 
| 1108 | 
 | 
| 1109 | echo "(" | json read
 | 
| 1110 | echo status=$?
 | 
| 1111 | 
 | 
| 1112 | echo ")" | json8 read
 | 
| 1113 | echo status=$?
 | 
| 1114 | 
 | 
| 1115 | ## STDOUT:
 | 
| 1116 | status=1
 | 
| 1117 | status=1
 | 
| 1118 | ## END
 | 
| 1119 | 
 | 
| 1120 | #### Data after internal NUL (issue #2026)
 | 
| 1121 | 
 | 
| 1122 | $SH <<'EOF'
 | 
| 1123 | pp line (fromJson(b'123\y00abc'))
 | 
| 1124 | EOF
 | 
| 1125 | echo status=$?
 | 
| 1126 | 
 | 
| 1127 | $SH <<'EOF'
 | 
| 1128 | pp line (fromJson(b'123\y01abc'))
 | 
| 1129 | EOF
 | 
| 1130 | echo status=$?
 | 
| 1131 | 
 | 
| 1132 | $SH <<'EOF'
 | 
| 1133 | shopt --set ysh:upgrade  # b'' syntax
 | 
| 1134 | json read <<< b'123\y00abc'
 | 
| 1135 | EOF
 | 
| 1136 | echo status=$?
 | 
| 1137 | 
 | 
| 1138 | $SH <<'EOF'
 | 
| 1139 | shopt --set ysh:upgrade  # b'' syntax
 | 
| 1140 | json read <<< b'123\y01abc'
 | 
| 1141 | EOF
 | 
| 1142 | echo status=$?
 | 
| 1143 | 
 | 
| 1144 | ## STDOUT:
 | 
| 1145 | status=4
 | 
| 1146 | status=4
 | 
| 1147 | status=1
 | 
| 1148 | status=1
 | 
| 1149 | ## END
 | 
| 1150 | 
 | 
| 1151 | #### Float too big
 | 
| 1152 | 
 | 
| 1153 | $SH <<'EOF'
 | 
| 1154 | json read <<< '123456789123456789123456789.12345e67890'
 | 
| 1155 | echo status=$?
 | 
| 1156 | pp line (_reply)
 | 
| 1157 | EOF
 | 
| 1158 | 
 | 
| 1159 | $SH <<'EOF'
 | 
| 1160 | json read <<< '-123456789123456789123456789.12345e67890'
 | 
| 1161 | echo status=$?
 | 
| 1162 | pp line (_reply)
 | 
| 1163 | EOF
 | 
| 1164 | 
 | 
| 1165 | ## STDOUT:
 | 
| 1166 | status=0
 | 
| 1167 | (Float)   inf
 | 
| 1168 | status=0
 | 
| 1169 | (Float)   -inf
 | 
| 1170 | ## END
 | 
| 1171 | 
 | 
| 1172 | #### Many [[[ , but not too many
 | 
| 1173 | 
 | 
| 1174 | shopt -s ysh:upgrade
 | 
| 1175 | 
 | 
| 1176 | proc pairs(n) {
 | 
| 1177 |   var m = int(n)  # TODO: 1 .. n should auto-convert?
 | 
| 1178 | 
 | 
| 1179 |   for i in (1 .. m) {
 | 
| 1180 |     write -n -- '['
 | 
| 1181 |   }
 | 
| 1182 |   for i in (1 .. m) {
 | 
| 1183 |     write -n -- ']'
 | 
| 1184 |   }
 | 
| 1185 | }
 | 
| 1186 | 
 | 
| 1187 | # This is all Python can handle; C++ can handle more
 | 
| 1188 | msg=$(pairs 50)
 | 
| 1189 | 
 | 
| 1190 | #echo $msg
 | 
| 1191 | 
 | 
| 1192 | echo "$msg" | json read
 | 
| 1193 | pp line (_reply)
 | 
| 1194 | echo len=$[len(_reply)]
 | 
| 1195 | 
 | 
| 1196 | ## STDOUT:
 | 
| 1197 | (List)   [[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]
 | 
| 1198 | len=1
 | 
| 1199 | ## END
 | 
| 1200 | 
 | 
| 1201 | 
 | 
| 1202 | #### Too many opening [[[ - blocking stack
 | 
| 1203 | 
 | 
| 1204 | python2 -c 'print("[" * 10000)' | json read
 | 
| 1205 | pp line (_reply)
 | 
| 1206 | 
 | 
| 1207 | python2 -c 'print("{" * 10000)' | json read
 | 
| 1208 | pp line (_reply)
 | 
| 1209 | 
 | 
| 1210 | ## STDOUT:
 | 
| 1211 | ## END
 | 
| 1212 | 
 |