Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: Crash when exporting scalar without value and getsparam fails



On Jan 10,  9:09am, Mikael Magnusson wrote:
} Subject: Re: Crash when exporting scalar without value and getsparam fails
}
} So just to check, I tried both of the things anyway. With setting it
} to "" on failure, it gets exported as the empty string, and this
}         if (!(pm->node.flags & PM_UNSET) && !pm->env && !value) {
}             void *foo = getsparam(pname);
}             if (foo)
}                 addenv(pm, foo);
}         }
} 
} results in almost the correct behaviour, except that after unsetting
} the parameter and setting it again, it still gets exported. (This
} doesn't happen for other parameters). Maybe bin_unset or unsetparam_pm
} has some special code that needs changing too?

I think the whole problem is that the PM_UNSET flag is for some reason
not set, even though the parameter is in fact unset.

This is happening at line 2075:

pm->node.flags = (pm->node.flags | (on & ~PM_READONLY)) & ~(off | PM_UNSET);

That line is never executed for e.g. "export FOO", because of this up at
line 1937:

    /*
     * We need to compare types with an existing pm if special,
     * even if that's unset
     */
    if (pm && (pm->node.flags & PM_SPECIAL))
	usepm = 1;

Consequently ...

diff --git a/Src/builtin.c b/Src/builtin.c
index 8abe728..8dee8f9 100644
--- a/Src/builtin.c
+++ b/Src/builtin.c
@@ -1935,7 +1935,7 @@ typeset_single(char *cname, char *pname, Param pm, UNUSED(int func),
      * even if that's unset
      */
     if (pm && (pm->node.flags & PM_SPECIAL))
-	usepm = 1;
+	usepm = 2;	/* indicate that we preserve the PM_UNSET flag */
 
     /*
      * Don't use an existing param if
@@ -2072,7 +2072,11 @@ typeset_single(char *cname, char *pname, Param pm, UNUSED(int func),
 		    arrfixenv(pm->node.nam, x);
 	    }
 	}
-	pm->node.flags = (pm->node.flags | (on & ~PM_READONLY)) & ~(off | PM_UNSET);
+	if (usepm == 2)		/* do not change the PM_UNSET flag */
+	    pm->node.flags = (pm->node.flags | (on & ~PM_READONLY)) & ~off;
+	else
+	    pm->node.flags = (pm->node.flags |
+			      (on & ~PM_READONLY)) & ~(off | PM_UNSET);
 	if (on & (PM_LEFT | PM_RIGHT_B | PM_RIGHT_Z)) {
 	    if (typeset_setwidth(cname, pm, ops, on, 0))
 		return NULL;



Messages sorted by: Reverse Date, Date, Thread, Author