From 73320cc4621ec9e4218047a9ef9b35aa9350ec55 Mon Sep 17 00:00:00 2001 From: shikokuchuo <53399081+shikokuchuo@users.noreply.github.com> Date: Wed, 29 Nov 2023 13:30:46 +0000 Subject: [PATCH] makes safe nextmode() --- src/core.c | 54 +++++++++++++++++++++++++++++------------------------- 1 file changed, 29 insertions(+), 25 deletions(-) diff --git a/src/core.c b/src/core.c index 7b8047170..231606f20 100644 --- a/src/core.c +++ b/src/core.c @@ -275,35 +275,39 @@ SEXP nano_unserialize(unsigned char *buf, const size_t sz) { size_t cur; SEXP reflist; - switch (buf[0]) { - case 66: - case 88: - offset = 0; - cur = 0; - break; - case 7: - if (buf[1]) { - offset = *(uint64_t *) (buf + 4); - if (offset) { - SEXP raw, call; - PROTECT(raw = Rf_allocVector(RAWSXP, sz - offset)); - memcpy(STDVEC_DATAPTR(raw), buf + offset, sz - offset); - PROTECT(call = Rf_lcons(nano_refHookOut, Rf_cons(raw, R_NilValue))); - PROTECT(reflist = Rf_eval(call, R_GlobalEnv)); - if (TYPEOF(reflist) != VECSXP) - Rf_error("unserialization refhook did not return a list"); + if (sz > 12) { + switch (buf[0]) { + case 66: + case 88: + offset = 0; + cur = 0; + goto resume; + case 7: + if (buf[1]) { + offset = *(uint64_t *) (buf + 4); + if (offset) { + SEXP raw, call; + PROTECT(raw = Rf_allocVector(RAWSXP, sz - offset)); + memcpy(STDVEC_DATAPTR(raw), buf + offset, sz - offset); + PROTECT(call = Rf_lcons(nano_refHookOut, Rf_cons(raw, R_NilValue))); + PROTECT(reflist = Rf_eval(call, R_GlobalEnv)); + if (TYPEOF(reflist) != VECSXP) + Rf_error("unserialization refhook did not return a list"); + } + cur = 12; + goto resume; } - cur = 12; - break; + offset = 0; + cur = 4; + goto resume; } - offset = 0; - cur = 4; - break; - default: - Rf_warning("received data could not be unserialized"); - return nano_decode(buf, sz, 8); } + Rf_warning("received data could not be unserialized"); + return nano_decode(buf, sz, 8); + + resume: ; + SEXP out; nano_buf nbuf; struct R_inpstream_st input_stream;