change the return value of SSNEW to SSize_t

The normal savestack index is an I32, but that counts in ANY
(which are typically the larger of pointer or IV sizes), this
meant is the save stack was large, but still nowhere need it's
limit, the result of SSNEW() could overflow.

So make the result SSize_t and adjust SSPTR() to match.

SSPTR() asserts to ensure the supplied type is the same size as
SSize_t to ensure callers are updated to handle the new limit.
This commit is contained in:
Tony Cook 2022-10-20 15:04:51 +11:00
parent fce4124fa7
commit 1a2b24d857
5 changed files with 21 additions and 21 deletions

View File

@ -1726,7 +1726,7 @@ Cp |void |savestack_grow_cnt |I32 need
Amd |void |save_aelem |NN AV* av|SSize_t idx|NN SV **sptr
Apd |void |save_aelem_flags|NN AV* av|SSize_t idx|NN SV **sptr \
|const U32 flags
Cpd |I32 |save_alloc |I32 size|I32 pad
Cpd |SSize_t|save_alloc |SSize_t size|I32 pad
Apdh |void |save_aptr |NN AV** aptr
Apdh |AV* |save_ary |NN GV* gv
Cp |void |save_bool |NN bool* boolp
@ -2969,7 +2969,7 @@ Sx |void |clear_placeholders |NN HV *hv|U32 items
#endif
#if defined(PERL_IN_MG_C)
S |void |save_magic_flags|I32 mgs_ix|NN SV *sv|U32 flags
S |void |save_magic_flags|SSize_t mgs_ix|NN SV *sv|U32 flags
S |int |magic_methpack |NN SV *sv|NN const MAGIC *mg|NN SV *meth
S |SV* |magic_methcall1|NN SV *sv|NN const MAGIC *mg \
|NN SV *meth|U32 flags \

10
mg.c
View File

@ -87,7 +87,7 @@ struct magic_state {
/* MGS is typedef'ed to struct magic_state in perl.h */
STATIC void
S_save_magic_flags(pTHX_ I32 mgs_ix, SV *sv, U32 flags)
S_save_magic_flags(pTHX_ SSize_t mgs_ix, SV *sv, U32 flags)
{
MGS* mgs;
bool bumped = FALSE;
@ -165,7 +165,7 @@ be >= C<SVt_PVMG>. See C<L</sv_magic>>.
int
Perl_mg_get(pTHX_ SV *sv)
{
const I32 mgs_ix = SSNEW(sizeof(MGS));
const SSize_t mgs_ix = SSNEW(sizeof(MGS));
bool saved = FALSE;
bool have_new = 0;
bool taint_only = TRUE; /* the only get method seen is taint */
@ -269,7 +269,7 @@ Do magic after a value is assigned to the SV. See C<L</sv_magic>>.
int
Perl_mg_set(pTHX_ SV *sv)
{
const I32 mgs_ix = SSNEW(sizeof(MGS));
const SSize_t mgs_ix = SSNEW(sizeof(MGS));
MAGIC* mg;
MAGIC* nextmg;
@ -307,7 +307,7 @@ Perl_mg_size(pTHX_ SV *sv)
for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
const MGVTBL* const vtbl = mg->mg_virtual;
if (vtbl && vtbl->svt_len) {
const I32 mgs_ix = SSNEW(sizeof(MGS));
const SSize_t mgs_ix = SSNEW(sizeof(MGS));
I32 len;
save_magic(mgs_ix, sv);
/* omit MGf_GSKIP -- not changed here */
@ -340,7 +340,7 @@ Clear something magical that the SV represents. See C<L</sv_magic>>.
int
Perl_mg_clear(pTHX_ SV *sv)
{
const I32 mgs_ix = SSNEW(sizeof(MGS));
const SSize_t mgs_ix = SSNEW(sizeof(MGS));
MAGIC* mg;
MAGIC *nextmg;

View File

@ -3453,7 +3453,7 @@ PERL_CALLCONV void Perl_save_adelete(pTHX_ AV *av, SSize_t key);
PERL_CALLCONV void Perl_save_aelem_flags(pTHX_ AV* av, SSize_t idx, SV **sptr, const U32 flags);
#define PERL_ARGS_ASSERT_SAVE_AELEM_FLAGS \
assert(av); assert(sptr)
PERL_CALLCONV I32 Perl_save_alloc(pTHX_ I32 size, I32 pad);
PERL_CALLCONV SSize_t Perl_save_alloc(pTHX_ SSize_t size, I32 pad);
#define PERL_ARGS_ASSERT_SAVE_ALLOC
PERL_CALLCONV void Perl_save_aptr(pTHX_ AV** aptr);
#define PERL_ARGS_ASSERT_SAVE_APTR \
@ -5836,7 +5836,7 @@ STATIC int S_magic_methpack(pTHX_ SV *sv, const MAGIC *mg, SV *meth);
assert(sv); assert(mg); assert(meth)
STATIC void S_restore_magic(pTHX_ const void *p);
#define PERL_ARGS_ASSERT_RESTORE_MAGIC
STATIC void S_save_magic_flags(pTHX_ I32 mgs_ix, SV *sv, U32 flags);
STATIC void S_save_magic_flags(pTHX_ SSize_t mgs_ix, SV *sv, U32 flags);
#define PERL_ARGS_ASSERT_SAVE_MAGIC_FLAGS \
assert(sv)
STATIC void S_unwind_handler_stack(pTHX_ const void *p);

View File

@ -1014,10 +1014,10 @@ function.
=cut
*/
I32
Perl_save_alloc(pTHX_ I32 size, I32 pad)
SSize_t
Perl_save_alloc(pTHX_ SSize_t size, I32 pad)
{
const I32 start = pad + ((char*)&PL_savestack[PL_savestack_ix]
const SSize_t start = pad + ((char*)&PL_savestack[PL_savestack_ix]
- (char*)PL_savestack);
const UV elems = 1 + ((size + pad - 1) / sizeof(*PL_savestack));
const UV elems_shifted = elems << SAVE_TIGHT_SHIFT;

18
scope.h
View File

@ -250,12 +250,12 @@ scope has the given name. C<name> must be a literal string.
/*
=for apidoc_section $stack
=for apidoc Am|I32|SSNEW |Size_t size
=for apidoc_item | |SSNEWa |Size_t_size|Size_t align
=for apidoc_item | |SSNEWat|Size_t_size|type|Size_t align
=for apidoc_item | |SSNEWt |Size_t size|type
=for apidoc Am|SSize_t|SSNEW |Size_t size
=for apidoc_item | |SSNEWa |Size_t_size|Size_t align
=for apidoc_item | |SSNEWat|Size_t_size|type|Size_t align
=for apidoc_item | |SSNEWt |Size_t size|type
These temporarily allocates data on the savestack, returning an I32 index into
These temporarily allocates data on the savestack, returning an SSize_t index into
the savestack, because a pointer would get broken if the savestack is moved on
reallocation. Use L</C<SSPTR>> to convert the returned index into a pointer.
@ -268,8 +268,8 @@ L</C<MEM_ALIGNBYTES>>. The alignment will be preserved through savestack
reallocation B<only> if realloc returns data aligned to a size divisible by
"align"!
=for apidoc Am|type |SSPTR |I32 index|type
=for apidoc_item|type *|SSPTRt|I32 index|type
=for apidoc Am|type |SSPTR |SSize_t index|type
=for apidoc_item|type *|SSPTRt|SSize_t index|type
These convert the C<index> returned by L/<C<SSNEW>> and kin into actual pointers.
@ -285,8 +285,8 @@ casts it to a pointer of that C<type>.
(I32)(align - ((size_t)((caddr_t)&PL_savestack[PL_savestack_ix]) % align)) % align)
#define SSNEWat(n,t,align) SSNEWa((n)*sizeof(t), align)
#define SSPTR(off,type) ((type) ((char*)PL_savestack + off))
#define SSPTRt(off,type) ((type*) ((char*)PL_savestack + off))
#define SSPTR(off,type) (assert(sizeof(off) == sizeof(SSize_t)), (type) ((char*)PL_savestack + off))
#define SSPTRt(off,type) (assert(sizeof(off) == sizeof(SSize_t)), (type*) ((char*)PL_savestack + off))
#define save_freesv(op) save_pushptr((void *)(op), SAVEt_FREESV)
#define save_mortalizesv(op) save_pushptr((void *)(op), SAVEt_MORTALIZESV)