java-topology/defects/perl5/patch/0001-pad-findlex-hash-lookup.patch

47 lines
1.7 KiB
Diff

# UNDF: UNDF-2026-000000210
--- a/pad.h
+++ b/pad.h
@@ -162,6 +162,8 @@ struct padnamelist {
SSize_t xpadnl_fill;
SSize_t xpadnl_max;
SSize_t xpadnl_max_named;
+ /* CWE-407 fix: string→offset hash for O(1) named-variable lookup */
+ HV *xpadnl_namehash;
U32 xpadnl_refcnt;
};
--- a/pad.c
+++ b/pad.c
@@ -543,6 +543,14 @@ Perl_pad_alloc_name(pTHX_ PADNAME *name, U32 flags, HV *typestash, HV *ourstash
padnamelist_store(PL_comppad_name, offset, name);
+
+ /* CWE-407 fix: record name → offset in the namehash for O(1) findlex */
+ if (PadnamePV(name) && !PadnameOUTER(name)) {
+ if (!PadnamelistNAMEHASH(PL_comppad_name))
+ PadnamelistNAMEHASH(PL_comppad_name) = newHV();
+ (void)hv_store(PadnamelistNAMEHASH(PL_comppad_name),
+ PadnamePV(name), PadnameLEN(name),
+ newSVuv((UV)offset), 0);
+ }
@@ -1168,6 +1176,18 @@ S_pad_findlex(...)
if (padlist) { /* not an undef CV */
PADOFFSET fake_offset = 0;
const PADNAMELIST * const names = PadlistNAMES(padlist);
PADNAME * const * const name_p = PadnamelistARRAY(names);
+ /* CWE-407 fix: O(1) hash lookup before the O(n) linear scan */
+ HV *nh = PadnamelistNAMEHASH(names);
+ if (nh) {
+ SV **svp = hv_fetch(nh, namepv, (I32)namelen, 0);
+ if (svp) {
+ PADOFFSET candidate = (PADOFFSET)SvUV(*svp);
+ const PADNAME *cn = name_p[candidate];
+ if (cn && !PadnameOUTER(cn) && PadnameIN_SCOPE(cn, seq)) {
+ offset = candidate;
+ goto found;
+ }
+ }
+ }
+
for (offset = PadnamelistMAXNAMED(names); offset > 0; offset--) {