Hello, Sergey, thanks for the patch! LGTM Sergey On 7/20/26 15:59, Sergey Kaplun wrote: > From: Mike Pall > > Reported by Huang Haiyang. > > (cherry picked from commit e4c7d8b38040518d42599eef8ddb5e67aa967a9c) > > The bitfield of packed structure uses the original type size, which > leads to heap-buffer-overflow access on conversions. > > This patch fixes it by adjusting the size of the bitfield container when > necessary. > > Sergey Kaplun: > * added the description and the test for the problem > > Part of tarantool/tarantool#12880 > --- > > Branch:https://github.com/tarantool/luajit/tree/skaplun/lj-1451-ffi-packed-bitfield > Related issues: > *https://github.com/LuaJIT/LuaJIT/issues/1451 > *https://github.com/tarantool/tarantool/issues/12880 > > src/lj_cparse.c | 2 ++ > .../lj-1451-ffi-packed-bitfield.test.lua | 28 +++++++++++++++++++ > 2 files changed, 30 insertions(+) > create mode 100644 test/tarantool-tests/lj-1451-ffi-packed-bitfield.test.lua > > diff --git a/src/lj_cparse.c b/src/lj_cparse.c > index ff23b44b..1b3ce7ec 100644 > --- a/src/lj_cparse.c > +++ b/src/lj_cparse.c > @@ -1341,6 +1341,8 @@ static void cp_struct_layout(CPState *cp, CTypeID sid, CTInfo sattr) > CTALIGN(lj_fls(sz)); > ct->size = (bofs >> 3); /* Store field offset. */ > } else { > + if (csz > amask+1 && bsz <= amask+1) > + csz = amask+1; /* Shrink container of packed bitfield. */ > ct->info = CTINFO(CT_BITFIELD, > (info & (CTF_QUAL|CTF_UNSIGNED|CTF_BOOL)) + > (csz << (CTSHIFT_BITCSZ-3)) + (bsz << CTSHIFT_BITBSZ)); > diff --git a/test/tarantool-tests/lj-1451-ffi-packed-bitfield.test.lua b/test/tarantool-tests/lj-1451-ffi-packed-bitfield.test.lua > new file mode 100644 > index 00000000..07e53f76 > --- /dev/null > +++ b/test/tarantool-tests/lj-1451-ffi-packed-bitfield.test.lua > @@ -0,0 +1,28 @@ > +local tap = require('tap') > + > +-- Test file to demonstrate LuaJIT's incorrect behaviour of the > +-- `#pragma` pack directive for bitfields in structures. > +-- See also:https://github.com/LuaJIT/LuaJIT/issues/1451. > + > +local test = tap.test('lj-1451-ffi-packed-bitfield') > + > +local ffi = require('ffi') > + > +ffi.cdef[[ > +#pragma pack(push, 2) > +typedef struct { > + unsigned intbitfield:1; > +} packed_struct; > +#pragma pack(pop) > +]] > + > +test:plan(2) > + > +local packed = ffi.new('packed_struct') > + > +test:is(packed.bitfield, 0, 'correct 0-initialization') > + > +packed.bitfield = 1 > +test:is(packed.bitfield, 1, 'bitfield set correctly') > + > +test:done(true)