From a689e9dc430613755ae49b0c46cb9ba6c59d0006 Mon Sep 17 00:00:00 2001 From: Mike Pall Date: Mon, 19 Jul 2021 16:45:26 +0200 Subject: [PATCH] String buffers, part 2f: Prevent self-put of buffer. Sponsored by fmad.io. --- src/lib_buffer.c | 1 + src/lj_errmsg.h | 1 + src/lj_strfmt.c | 5 ++++- 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/lib_buffer.c b/src/lib_buffer.c index f13320c4..cb7531a2 100644 --- a/src/lib_buffer.c +++ b/src/lib_buffer.c @@ -126,6 +126,7 @@ LJLIB_CF(buffer_method_put) lj_strfmt_putfnum((SBuf *)sbx, STRFMT_G14, numV(o)); } else if (tvisbuf(o)) { SBufExt *sbx2 = bufV(o); + if (sbx2 == sbx) lj_err_arg(L, arg+1, LJ_ERR_BUFFER_SELF); lj_buf_putmem((SBuf *)sbx, sbx2->r, sbufxlen(sbx2)); } else if (!mo && !tvisnil(mo = lj_meta_lookup(L, o, MM_tostring))) { /* Call __tostring metamethod inline. */ diff --git a/src/lj_errmsg.h b/src/lj_errmsg.h index 56be4bb9..89e67496 100644 --- a/src/lj_errmsg.h +++ b/src/lj_errmsg.h @@ -182,6 +182,7 @@ ERRDEF(FFI_NYICALL, "NYI: cannot call this C function (yet)") #if LJ_HASBUFFER /* String buffer errors. */ +ERRDEF(BUFFER_SELF, "cannot put buffer into itself") ERRDEF(BUFFER_BADOPT, "bad options table") ERRDEF(BUFFER_BADENC, "cannot serialize " LUA_QS) ERRDEF(BUFFER_BADDEC, "cannot deserialize tag 0x%02x") diff --git a/src/lj_strfmt.c b/src/lj_strfmt.c index 7b073470..945954aa 100644 --- a/src/lj_strfmt.c +++ b/src/lj_strfmt.c @@ -431,7 +431,7 @@ int lj_strfmt_putarg(lua_State *L, SBuf *sb, int arg, int retry) MSize len; const char *s; cTValue *mo; - if (LJ_UNLIKELY(!tvisstr(o)) && retry >= 0 && + if (LJ_UNLIKELY(!tvisstr(o) && !tvisbuf(o)) && retry >= 0 && !tvisnil(mo = lj_meta_lookup(L, o, MM_tostring))) { /* Call __tostring metamethod once. */ copyTV(L, L->top++, mo); @@ -447,10 +447,13 @@ int lj_strfmt_putarg(lua_State *L, SBuf *sb, int arg, int retry) if (LJ_LIKELY(tvisstr(o))) { len = strV(o)->len; s = strVdata(o); +#if LJ_HASBUFFER } else if (tvisbuf(o)) { SBufExt *sbx = bufV(o); + if (sbx == (SBufExt *)sb) lj_err_arg(L, arg+1, LJ_ERR_BUFFER_SELF); len = sbufxlen(sbx); s = sbx->r; +#endif } else { GCstr *str = lj_strfmt_obj(L, o); len = str->len;