diff options
| author | Mike Pall <mike> | 2021-08-12 21:28:17 +0200 |
|---|---|---|
| committer | Mike Pall <mike> | 2021-08-12 21:28:17 +0200 |
| commit | 8ff09d9f5ad5b037926be2a50dc32b681c5e7597 (patch) | |
| tree | 2df5881cf880d078aeae132e63d37cdc29ce6796 | |
| parent | 15ed84bd499b3ecdba9f431f2d24696a313227e4 (diff) | |
| download | luajit-8ff09d9f5ad5b037926be2a50dc32b681c5e7597.tar.gz luajit-8ff09d9f5ad5b037926be2a50dc32b681c5e7597.tar.bz2 luajit-8ff09d9f5ad5b037926be2a50dc32b681c5e7597.zip | |
String buffers, part 4b: Improve de-serialization checks.
Sponsored by fmad.io.
| -rw-r--r-- | src/lj_serialize.c | 16 |
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. */ |
| 469 | char * LJ_FASTCALL lj_serialize_get(SBufExt *sbx, TValue *o) | 477 | char * 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 | ||
