Skip to content

Commit b66a2e2

Browse files
paltherrbartschaefer
authored andcommitted
53798: report reference loops created when a reference goes out of scope
1 parent 938b3c9 commit b66a2e2

File tree

4 files changed

+49
-16
lines changed

4 files changed

+49
-16
lines changed

ChangeLog

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@
2020
* Philippe: 53790: Src/builtin.c, Test/K01nameref.ztst,
2121
Test/V10private.ztst: corrections to reference loop detection
2222

23+
* Philippe: 53798: Src/params.c, Src/zsh.h, Test/K01nameref.ztst:
24+
report reference loops created when a reference goes out of scope
25+
2326
2025-10-24 Oliver Kiddle <[email protected]>
2427

2528
* 54002: Src/parse.c: silence compiler warning for static function

Src/params.c

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6278,19 +6278,19 @@ resolve_nameref(Param pm, const Asgment stop)
62786278

62796279
if (pm && (pm->node.flags & PM_NAMEREF)) {
62806280
char *refname = GETREFNAME(pm);
6281-
if (pm->node.flags & (PM_UNSET|PM_TAGGED)) {
6281+
if (pm->node.flags & PM_TAGGED) {
6282+
zerr("%s: invalid self reference", pm->node.nam);
6283+
return NULL;
6284+
} else if (pm->node.flags & PM_UNSET) {
62826285
/* Semaphore with createparam() */
62836286
pm->node.flags &= ~PM_UNSET;
62846287
if (pm->node.flags & PM_NEWREF) /* See setloopvar() */
62856288
return NULL;
6286-
if (refname && *refname && (pm->node.flags & PM_TAGGED))
6287-
pm->node.flags |= PM_SELFREF; /* See setscope() */
62886289
return (HashNode) pm;
62896290
} else if (refname) {
6290-
if ((pm->node.flags & PM_TAGGED) ||
6291-
(stop && strcmp(refname, stop->name) == 0)) {
6291+
if (stop && strcmp(refname, stop->name) == 0) {
62926292
/* zwarnnam(refname, "invalid self reference"); */
6293-
return stop ? (HashNode)pm : NULL;
6293+
return (HashNode)pm;
62946294
}
62956295
if (*refname)
62966296
seek = refname;
@@ -6418,15 +6418,7 @@ setscope(Param pm)
64186418
if (basepm) {
64196419
if (basepm->node.flags & PM_NAMEREF) {
64206420
if (pm == basepm) {
6421-
if (pm->node.flags & PM_SELFREF) {
6422-
/* Loop signalled by resolve_nameref() */
6423-
if (upscope(pm, pm->base) == pm) {
6424-
zerr("%s: invalid self reference", refname);
6425-
unsetparam_pm(pm, 0, 1);
6426-
break;
6427-
}
6428-
pm->node.flags &= ~PM_SELFREF;
6429-
} else if (pm->base == pm->level) {
6421+
if (pm->base == pm->level) {
64306422
if (refname && *refname &&
64316423
strcmp(pm->node.nam, refname) == 0) {
64326424
zerr("%s: invalid self reference", refname);

Src/zsh.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1935,7 +1935,6 @@ struct tieddata {
19351935
#define PM_NAMEDDIR (1<<29) /* has a corresponding nameddirtab entry */
19361936
#define PM_NAMEREF (1<<30) /* pointer to a different parameter */
19371937

1938-
#define PM_SELFREF PM_UNIQUE /* Overload when namerefs resolved */
19391938
#define PM_NEWREF PM_SINGLE /* Overload in for-loop namerefs */
19401939

19411940
/* The option string corresponds to the first of the variables above */

Test/K01nameref.ztst

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1315,4 +1315,43 @@ F:previously this could create an infinite recursion and crash
13151315
>ref1=var2
13161316
>ref2=var2
13171317

1318+
typeset -n ref1
1319+
typeset -n ref2=ref1;
1320+
() {
1321+
typeset ref2=foo
1322+
ref1=ref2
1323+
}
1324+
echo reached
1325+
echo $ref1
1326+
echo NOT REACHED
1327+
1:expansion of incidental reference loop triggers error
1328+
>reached
1329+
*?*: ref1: invalid self reference
1330+
1331+
typeset -n ref1
1332+
typeset -n ref2=ref1;
1333+
() {
1334+
typeset ref2=foo
1335+
ref1=ref2
1336+
}
1337+
echo reached
1338+
ref1=foo
1339+
echo NOT REACHED
1340+
1:assignment to incidental reference loop triggers error
1341+
>reached
1342+
*?*: ref1: invalid self reference
1343+
1344+
typeset -n ref1
1345+
typeset -n ref2=ref1;
1346+
() {
1347+
typeset ref2=foo
1348+
ref1=ref2
1349+
}
1350+
echo reached
1351+
typeset -n ref3=ref1
1352+
echo NOT REACHED
1353+
1:reference to incidental reference loop triggers error
1354+
>reached
1355+
*?*: ref1: invalid self reference
1356+
13181357
%clean

0 commit comments

Comments
 (0)