aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lj_serialize.c16
1 files changed, 13 insertions, 3 deletions
diff --git a/src/lj_serialize.c b/src/lj_serialize.c
index e12e3668..d6551b11 100644
--- a/src/lj_serialize.c
+++ b/src/lj_serialize.c
@@ -355,13 +355,13 @@ static char *serialize_get(char *r, SBufExt *sbx, TValue *o)
355#if LJ_BE 355#if LJ_BE
356 o->u64 = lj_bswap64(o->u64); 356 o->u64 = lj_bswap64(o->u64);
357#endif 357#endif
358 if (!tvisnum(o)) setnanV(o); 358 if (!tvisnum(o)) setnanV(o); /* Fix non-canonical NaNs. */
359 } else if (tp <= SER_TAG_TRUE) { 359 } else if (tp <= SER_TAG_TRUE) {
360 setpriV(o, ~tp); 360 setpriV(o, ~tp);
361 } else if (tp == SER_TAG_DICT_STR) { 361 } else if (tp == SER_TAG_DICT_STR) {
362 GCtab *dict_str; 362 GCtab *dict_str;
363 uint32_t idx; 363 uint32_t idx;
364 r = serialize_ru124(r, w, &idx); 364 r = serialize_ru124(r, w, &idx); if (LJ_UNLIKELY(!r)) goto eob;
365 idx++; 365 idx++;
366 dict_str = tabref(sbx->dict_str); 366 dict_str = tabref(sbx->dict_str);
367 if (dict_str && idx < dict_str->asize && tvisstr(arrayslot(dict_str, idx))) 367 if (dict_str && idx < dict_str->asize && tvisstr(arrayslot(dict_str, idx)))
@@ -371,6 +371,8 @@ static char *serialize_get(char *r, SBufExt *sbx, TValue *o)
371 } else if (tp >= SER_TAG_TAB && tp <= SER_TAG_DICT_MT) { 371 } else if (tp >= SER_TAG_TAB && tp <= SER_TAG_DICT_MT) {
372 uint32_t narray = 0, nhash = 0; 372 uint32_t narray = 0, nhash = 0;
373 GCtab *t, *mt = NULL; 373 GCtab *t, *mt = NULL;
374 if (sbx->depth <= 0) lj_err_caller(sbufL(sbx), LJ_ERR_BUFFER_DEPTH);
375 sbx->depth--;
374 if (tp == SER_TAG_DICT_MT) { 376 if (tp == SER_TAG_DICT_MT) {
375 GCtab *dict_mt; 377 GCtab *dict_mt;
376 uint32_t idx; 378 uint32_t idx;
@@ -409,6 +411,7 @@ static char *serialize_get(char *r, SBufExt *sbx, TValue *o)
409 r = serialize_get(r, sbx, v); 411 r = serialize_get(r, sbx, v);
410 } while (--nhash); 412 } while (--nhash);
411 } 413 }
414 sbx->depth++;
412#if LJ_HASFFI 415#if LJ_HASFFI
413 } else if (tp >= SER_TAG_INT64 && tp <= SER_TAG_COMPLEX) { 416 } else if (tp >= SER_TAG_INT64 && tp <= SER_TAG_COMPLEX) {
414 uint32_t sz = tp == SER_TAG_COMPLEX ? 16 : 8; 417 uint32_t sz = tp == SER_TAG_COMPLEX ? 16 : 8;
@@ -424,6 +427,11 @@ static char *serialize_get(char *r, SBufExt *sbx, TValue *o)
424 if (sz == 16) 427 if (sz == 16)
425 ((uint64_t *)cdataptr(cd))[1] = lj_bswap64(((uint64_t *)cdataptr(cd))[1]); 428 ((uint64_t *)cdataptr(cd))[1] = lj_bswap64(((uint64_t *)cdataptr(cd))[1]);
426#endif 429#endif
430 if (sz == 16) { /* Fix non-canonical NaNs. */
431 TValue *cdo = (TValue *)cdataptr(cd);
432 if (!tvisnum(&cdo[0])) setnanV(&cdo[0]);
433 if (!tvisnum(&cdo[1])) setnanV(&cdo[1]);
434 }
427 setcdataV(sbufL(sbx), o, cd); 435 setcdataV(sbufL(sbx), o, cd);
428#endif 436#endif
429 } else if (tp <= (LJ_64 ? SER_TAG_LIGHTUD64 : SER_TAG_LIGHTUD32)) { 437 } else if (tp <= (LJ_64 ? SER_TAG_LIGHTUD64 : SER_TAG_LIGHTUD32)) {
@@ -468,6 +476,7 @@ SBufExt * LJ_FASTCALL lj_serialize_put(SBufExt *sbx, cTValue *o)
468/* Decode from buffer. */ 476/* Decode from buffer. */
469char * LJ_FASTCALL lj_serialize_get(SBufExt *sbx, TValue *o) 477char * LJ_FASTCALL lj_serialize_get(SBufExt *sbx, TValue *o)
470{ 478{
479 sbx->depth = LJ_SERIALIZE_DEPTH;
471 return serialize_get(sbx->r, sbx, o); 480 return serialize_get(sbx->r, sbx, o);
472} 481}
473 482
@@ -491,7 +500,8 @@ void lj_serialize_decode(lua_State *L, TValue *o, GCstr *str)
491 memset(&sbx, 0, sizeof(SBufExt)); 500 memset(&sbx, 0, sizeof(SBufExt));
492 lj_bufx_set_cow(L, &sbx, strdata(str), str->len); 501 lj_bufx_set_cow(L, &sbx, strdata(str), str->len);
493 /* No need to set sbx.cowref here. */ 502 /* No need to set sbx.cowref here. */
494 r = lj_serialize_get(&sbx, o); 503 sbx.depth = LJ_SERIALIZE_DEPTH;
504 r = serialize_get(sbx.r, &sbx, o);
495 if (r != sbx.w) lj_err_caller(L, LJ_ERR_BUFFER_LEFTOV); 505 if (r != sbx.w) lj_err_caller(L, LJ_ERR_BUFFER_LEFTOV);
496} 506}
497 507