From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 3603 invoked from network); 7 Jan 1997 17:28:22 -0000 Received: from euclid.skiles.gatech.edu (list@130.207.146.50) by coral.primenet.com.au with SMTP; 7 Jan 1997 17:28:21 -0000 Received: (from list@localhost) by euclid.skiles.gatech.edu (8.7.3/8.7.3) id MAA24862; Tue, 7 Jan 1997 12:09:24 -0500 (EST) Resent-Date: Tue, 7 Jan 1997 12:09:24 -0500 (EST) From: Zoltan Hidvegi Message-Id: <199701071709.SAA24255@bolyai.cs.elte.hu> Subject: Re: readonly bug In-Reply-To: <199701071356.OAA09615@sgi.ifh.de> from Peter Stephenson at "Jan 7, 97 02:56:40 pm" To: pws@ifh.de (Peter Stephenson) Date: Tue, 7 Jan 1997 18:09:25 +0100 (MET) Cc: zsh-workers@math.gatech.edu Organization: Dept. of Comp. Sci., Eotvos University, Budapest, Hungary Phone: (36 1)2669833 ext: 2667, home phone: (36 1) 2752368 X-Mailer: ELM [version 2.4ME+ PL27 (25)] MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Resent-Message-ID: <"sVZiv1.0.P46.3Deqo"@euclid> Resent-From: zsh-workers@math.gatech.edu X-Mailing-List: archive/latest/2739 X-Loop: zsh-workers@math.gatech.edu Precedence: list Resent-Sender: zsh-workers-request@math.gatech.edu Peter Stephenson wrote: > haven't time to check this out further just now: > (there was some IFS stuff around to make this useful but it turns out that's > not necessary) > > % readonly vers=foo > % vers=(${=ZSH_VERSION}) > Segmentation fault (core dumped) Unfortunately read-only variables are not handled very well in most places. Here is a fix. After that zsh prints error message when you attempt to change a read-only variable. Patch applies to both zsh-3.0.2 and zsh-3.1.0 It makes createparam() fail and return NULL when you attempt to crearte an existing non-local parameter. Zoltan *** Src/builtin.c 1997/01/05 23:33:32 3.1.1.10 --- Src/builtin.c 1997/01/07 16:27:56 *************** *** 1842,1847 **** --- 1842,1851 ---- } } else { if (bit) { + if (pm->flags & PM_READONLY) { + on |= ~off & PM_READONLY; + pm->flags &= ~PM_READONLY; + } if (!asg->value) asg->value = dupstring(getsparam(asg->name)); unsetparam(asg->name); *************** *** 1850,1857 **** addlinknode(locallist, ztrdup(asg->name)); } LASTALLOC; } ! /* create a new node for a parameter with the flags in `on' minus the readonly flag */ pm = createparam(ztrdup(asg->name), on & ~PM_READONLY); pm->ct = auxlen; if (func != BIN_EXPORT) pm->level = locallevel; --- 1854,1863 ---- addlinknode(locallist, ztrdup(asg->name)); } LASTALLOC; } ! /* create a new node for a parameter with the * ! * flags in `on' minus the readonly flag */ pm = createparam(ztrdup(asg->name), on & ~PM_READONLY); + DPUTS(!pm, "BUG: parameter not created"); pm->ct = auxlen; if (func != BIN_EXPORT) pm->level = locallevel; *** Src/exec.c 1997/01/06 20:41:03 3.1.1.6 --- Src/exec.c 1997/01/07 16:09:45 *************** *** 1806,1813 **** if (removelist) { /* remove temporary parameters */ ! while ((s = (char *) ugetnode(removelist))) ! unsetparam(s); } if (restorelist) { --- 1806,1818 ---- if (removelist) { /* remove temporary parameters */ ! while ((s = (char *) ugetnode(removelist))) { ! if ((pm = (Param) paramtab->getnode(paramtab, s)) && ! !(pm->flags & PM_SPECIAL)) { ! pm->flags &= ~PM_READONLY; ! unsetparam_pm(pm, 0); ! } ! } } if (restorelist) { *** params.c 1997/01/05 21:07:31 3.1.1.7 --- params.c 1997/01/07 16:56:19 *************** *** 173,187 **** spec = oldpm && (oldpm->flags & PM_SPECIAL); if ((oldpm && oldpm->level == locallevel) || spec) { pm = oldpm; pm->ct = 0; oldpm = pm->old; ! pm->flags = (flags & (PM_EXPORTED | PM_LEFT | PM_RIGHT_B | PM_RIGHT_Z | ! PM_LOWER | PM_UPPER | PM_READONLY | PM_TAGGED)) | (pm->flags & (PM_SCALAR | PM_INTEGER | PM_ARRAY | PM_SPECIAL)); ! if (pm->ename && (altpm = (Param) paramtab->getnode(paramtab, pm->ename))) { ! altpm->flags &= ~(PM_UNSET | PM_EXPORTED | PM_LEFT | PM_RIGHT_B | ! PM_RIGHT_Z | PM_LOWER | PM_UPPER | PM_READONLY | PM_TAGGED); } } else { pm = (Param) zcalloc(sizeof *pm); --- 173,192 ---- spec = oldpm && (oldpm->flags & PM_SPECIAL); if ((oldpm && oldpm->level == locallevel) || spec) { + if (oldpm && !(oldpm->flags & PM_UNSET)) + return NULL; pm = oldpm; pm->ct = 0; oldpm = pm->old; ! pm->flags = (flags & (PM_EXPORTED | PM_LEFT | PM_RIGHT_B | ! PM_RIGHT_Z | PM_LOWER | PM_UPPER | ! PM_READONLY | PM_TAGGED | PM_UNIQUE)) | (pm->flags & (PM_SCALAR | PM_INTEGER | PM_ARRAY | PM_SPECIAL)); ! if (pm->ename && ! (altpm = (Param) paramtab->getnode(paramtab, pm->ename))) { ! altpm->flags &= ~(PM_UNSET | PM_UNIQUE | PM_UPPER | PM_LEFT | ! PM_RIGHT_B | PM_RIGHT_Z | PM_LOWER | ! PM_READONLY | PM_TAGGED | PM_EXPORTED); } } else { pm = (Param) zcalloc(sizeof *pm); *************** *** 771,776 **** --- 776,782 ---- MUSTUSEHEAP("setstrvalue"); if (v->pm->flags & PM_READONLY) { + zerr("read-only variable: %s", v->pm->nam, 0); zsfree(val); return; } *************** *** 847,854 **** { char buf[DIGBUFSIZE]; ! if (v->pm->flags & PM_READONLY) return; switch (PM_TYPE(v->pm->flags)) { case PM_SCALAR: case PM_ARRAY: --- 853,862 ---- { char buf[DIGBUFSIZE]; ! if (v->pm->flags & PM_READONLY) { ! zerr("read-only variable: %s", v->pm->nam, 0); return; + } switch (PM_TYPE(v->pm->flags)) { case PM_SCALAR: case PM_ARRAY: *************** *** 880,885 **** --- 888,894 ---- setarrvalue(Value v, char **val) { if (v->pm->flags & PM_READONLY) { + zerr("read-only variable: %s", v->pm->nam, 0); freearray(val); return; } *************** *** 1060,1065 **** --- 1069,1075 ---- } if (!(v = getvalue(&s, 1))) { pm = createparam(t, PM_INTEGER); + DPUTS(!pm, "BUG: parameter not created"); pm->u.val = val; return pm; } *************** *** 1088,1095 **** Param oldpm, altpm; int spec; ! if ((pm->flags & PM_READONLY) && pm->level <= locallevel) return; spec = (pm->flags & PM_SPECIAL) && !pm->level; switch (PM_TYPE(pm->flags)) { case PM_SCALAR: --- 1098,1107 ---- Param oldpm, altpm; int spec; ! if ((pm->flags & PM_READONLY) && pm->level <= locallevel) { ! zerr("read-only variable: %s", pm->nam, 0); return; + } spec = (pm->flags & PM_SPECIAL) && !pm->level; switch (PM_TYPE(pm->flags)) { case PM_SCALAR: