From 5d466de467f28ae6f7125bef086d141a7734a4ce Mon Sep 17 00:00:00 2001 From: ian Date: Thu, 19 Sep 2002 13:27:29 +0000 Subject: [PATCH] Fix memory and type management bugs. --- base/chiark-tcl.h | 3 ++- base/enum.c | 1 + base/hook.c | 2 +- base/parse.c | 22 +++++++++++++--------- base/tables-examples.tct | 2 +- base/tcmdifgen | 2 +- crypto/crypto.c | 1 + dgram/dgram.c | 10 ++++------ dgram/sockaddr.c | 2 +- hbytes/hbytes.h | 3 ++- hbytes/hook.c | 2 +- hbytes/parse.c | 22 +++++++++++++--------- hbytes/ulongs.c | 1 + 13 files changed, 42 insertions(+), 31 deletions(-) diff --git a/base/chiark-tcl.h b/base/chiark-tcl.h index ac19c8f..c9975f2 100644 --- a/base/chiark-tcl.h +++ b/base/chiark-tcl.h @@ -15,7 +15,7 @@ * * hbytes range VALUE START SIZE => substring (or error) * hbytes overwrite VAR START VALUE - * hbytes trimleft VALUE removes any leading 0 octets + * hbytes trimleft VAR removes any leading 0 octets * hbytes repeat VALUE COUNT => COUNT copies of VALUE * * hbytes clockincrement VAR INTEGER adds INTEGER to VAR mod 256^|VAR| @@ -175,6 +175,7 @@ void obj_updatestr_string(Tcl_Obj *o, const char *str); typedef struct { HBytes_Value *hb; Tcl_Obj *obj, *var; + int copied; } HBytes_Var; void fini_hbv(Tcl_Interp *ip, int rc, HBytes_Var *agg); diff --git a/base/enum.c b/base/enum.c index 8041cd3..e3fa041 100644 --- a/base/enum.c +++ b/base/enum.c @@ -8,6 +8,7 @@ static void enum_nt_dup(Tcl_Obj *src, Tcl_Obj *dup) { dup->internalRep= src->internalRep; + dup->typePtr= src->typePtr; } static void enum_nt_ustr(Tcl_Obj *o) { diff --git a/base/hook.c b/base/hook.c index 0adb6b5..cdcb246 100644 --- a/base/hook.c +++ b/base/hook.c @@ -61,10 +61,10 @@ int do_hbytes_rep_info(ClientData cd, Tcl_Interp *ip, } static void hbytes_t_dup(Tcl_Obj *src, Tcl_Obj *dup) { - objfreeir(dup); hbytes_array(OBJ_HBYTES(dup), hbytes_data(OBJ_HBYTES(src)), hbytes_len(OBJ_HBYTES(src))); + dup->typePtr= &hbytes_type; } static void hbytes_t_free(Tcl_Obj *o) { diff --git a/base/parse.c b/base/parse.c index b81511c..c203be1 100644 --- a/base/parse.c +++ b/base/parse.c @@ -30,31 +30,35 @@ int pat_hbv(Tcl_Interp *ip, Tcl_Obj *var, HBytes_Var *agg) { int rc; Tcl_Obj *val; - Tcl_IncrRefCount(var); agg->var= var; val= Tcl_ObjGetVar2(ip,var,0,TCL_LEAVE_ERR_MSG); if (!val) return TCL_ERROR; - if (Tcl_IsShared(val)) val= Tcl_DuplicateObj(val); - Tcl_IncrRefCount(val); - agg->obj= val; - + rc= Tcl_ConvertToType(ip,val,&hbytes_type); if (rc) return rc; - agg->hb= OBJ_HBYTES(val); return TCL_OK; } + Tcl_InvalidateStringRep(val); + if (Tcl_IsShared(val)) { + val= Tcl_DuplicateObj(val); + agg->copied= 1; + } + agg->obj= val; + + agg->hb= OBJ_HBYTES(val); + return TCL_OK; +} void fini_hbv(Tcl_Interp *ip, int rc, HBytes_Var *agg) { Tcl_Obj *ro; - if (agg->obj) Tcl_InvalidateStringRep(agg->obj); if (!rc) { assert(agg->obj); ro= Tcl_ObjSetVar2(ip,agg->var,0,agg->obj,TCL_LEAVE_ERR_MSG); if (!ro) rc= TCL_ERROR; } - if (agg->obj) Tcl_DecrRefCount(agg->obj); - if (agg->var) Tcl_DecrRefCount(agg->var); + if (rc && agg->copied) + Tcl_DecrRefCount(agg->obj); } int pat_hb(Tcl_Interp *ip, Tcl_Obj *obj, HBytes_Value *val) { diff --git a/base/tables-examples.tct b/base/tables-examples.tct index c130136..9a19c5a 100644 --- a/base/tables-examples.tct +++ b/base/tables-examples.tct @@ -2,7 +2,7 @@ Type hb: HBytes_Value @ Init hb hbytes_sentinel(&@); Type hbv: HBytes_Var @ -Init hbv @.hb=0; @.obj=0; @.var=0; +Init hbv @.hb=0; @.obj=0; @.var=0; @.copied=0; Fini hbv fini_hbv(ip, rc, &@); Type sockaddr: SockAddr_Value @ diff --git a/base/tcmdifgen b/base/tcmdifgen index dce3153..1456770 100755 --- a/base/tcmdifgen +++ b/base/tcmdifgen @@ -248,7 +248,7 @@ foreach $c_table (sort keys %tables) { $pa_vars .= " const char *e;\n"; $pa_fini .= "\n"; $pa_fini .= "e_err:\n"; - $pa_fini .= " setstringresult(ip,e);"; + $pa_fini .= " setstringresult(ip,e);\n"; $pa_fini .= " rc= TCL_ERROR; goto rc_err;\n"; } $pa_vars .= "\n"; diff --git a/crypto/crypto.c b/crypto/crypto.c index efddecd..457dc9e 100644 --- a/crypto/crypto.c +++ b/crypto/crypto.c @@ -102,6 +102,7 @@ static void key_t_dup(Tcl_Obj *src_obj, Tcl_Obj *dup_obj) { memcpy(dup->value, src->value, src->valuelen); noalg(dup); dup_obj->internalRep.otherValuePtr= dup; + dup_obj->typePtr= &blockcipherkey_type; } static void key_t_ustr(Tcl_Obj *o) { diff --git a/dgram/dgram.c b/dgram/dgram.c index bb538bf..0dd40aa 100644 --- a/dgram/dgram.c +++ b/dgram/dgram.c @@ -146,17 +146,14 @@ static void recv_call(ClientData sock_cd, int mask) { Tcl_IncrRefCount(invoke); rc= Tcl_ListObjReplace(ip,invoke,sock->script_llength,0,3,args); + for (i=0; i<3; i++) { Tcl_DecrRefCount(args[i]); args[i]= 0; } if (rc) goto x_rc; rc= Tcl_EvalObjEx(ip,invoke,TCL_EVAL_GLOBAL|TCL_EVAL_DIRECT); - for (i=0; i<3; i++) Tcl_DecrRefCount(args[i]); - Tcl_DecrRefCount(invoke); - - hbytes_free(&message_val); - sockaddr_free(&peer_val); - x_rc: + if (invoke) Tcl_DecrRefCount(invoke); + if (rc) Tcl_BackgroundError(ip); } @@ -225,6 +222,7 @@ static void sockid_t_free(Tcl_Obj *o) { } static void sockid_t_dup(Tcl_Obj *src, Tcl_Obj *dup) { dup->internalRep= src->internalRep; + dup->typePtr= &dgramsockid_type; } static void sockid_t_ustr(Tcl_Obj *o) { diff --git a/dgram/sockaddr.c b/dgram/sockaddr.c index 2a388d0..a191cac 100644 --- a/dgram/sockaddr.c +++ b/dgram/sockaddr.c @@ -62,10 +62,10 @@ void sockaddr_free(const SockAddr_Value *v) { /* Sockaddr Tcl type */ static void sockaddr_t_dup(Tcl_Obj *src, Tcl_Obj *dup) { - objfreeir(dup); sockaddr_create(OBJ_SOCKADDR(dup), sockaddr_addr(OBJ_SOCKADDR(src)), sockaddr_len(OBJ_SOCKADDR(src))); + dup->typePtr= &hbytes_type; } static void sockaddr_t_free(Tcl_Obj *o) { diff --git a/hbytes/hbytes.h b/hbytes/hbytes.h index ac19c8f..c9975f2 100644 --- a/hbytes/hbytes.h +++ b/hbytes/hbytes.h @@ -15,7 +15,7 @@ * * hbytes range VALUE START SIZE => substring (or error) * hbytes overwrite VAR START VALUE - * hbytes trimleft VALUE removes any leading 0 octets + * hbytes trimleft VAR removes any leading 0 octets * hbytes repeat VALUE COUNT => COUNT copies of VALUE * * hbytes clockincrement VAR INTEGER adds INTEGER to VAR mod 256^|VAR| @@ -175,6 +175,7 @@ void obj_updatestr_string(Tcl_Obj *o, const char *str); typedef struct { HBytes_Value *hb; Tcl_Obj *obj, *var; + int copied; } HBytes_Var; void fini_hbv(Tcl_Interp *ip, int rc, HBytes_Var *agg); diff --git a/hbytes/hook.c b/hbytes/hook.c index 0adb6b5..cdcb246 100644 --- a/hbytes/hook.c +++ b/hbytes/hook.c @@ -61,10 +61,10 @@ int do_hbytes_rep_info(ClientData cd, Tcl_Interp *ip, } static void hbytes_t_dup(Tcl_Obj *src, Tcl_Obj *dup) { - objfreeir(dup); hbytes_array(OBJ_HBYTES(dup), hbytes_data(OBJ_HBYTES(src)), hbytes_len(OBJ_HBYTES(src))); + dup->typePtr= &hbytes_type; } static void hbytes_t_free(Tcl_Obj *o) { diff --git a/hbytes/parse.c b/hbytes/parse.c index b81511c..c203be1 100644 --- a/hbytes/parse.c +++ b/hbytes/parse.c @@ -30,31 +30,35 @@ int pat_hbv(Tcl_Interp *ip, Tcl_Obj *var, HBytes_Var *agg) { int rc; Tcl_Obj *val; - Tcl_IncrRefCount(var); agg->var= var; val= Tcl_ObjGetVar2(ip,var,0,TCL_LEAVE_ERR_MSG); if (!val) return TCL_ERROR; - if (Tcl_IsShared(val)) val= Tcl_DuplicateObj(val); - Tcl_IncrRefCount(val); - agg->obj= val; - + rc= Tcl_ConvertToType(ip,val,&hbytes_type); if (rc) return rc; - agg->hb= OBJ_HBYTES(val); return TCL_OK; } + Tcl_InvalidateStringRep(val); + if (Tcl_IsShared(val)) { + val= Tcl_DuplicateObj(val); + agg->copied= 1; + } + agg->obj= val; + + agg->hb= OBJ_HBYTES(val); + return TCL_OK; +} void fini_hbv(Tcl_Interp *ip, int rc, HBytes_Var *agg) { Tcl_Obj *ro; - if (agg->obj) Tcl_InvalidateStringRep(agg->obj); if (!rc) { assert(agg->obj); ro= Tcl_ObjSetVar2(ip,agg->var,0,agg->obj,TCL_LEAVE_ERR_MSG); if (!ro) rc= TCL_ERROR; } - if (agg->obj) Tcl_DecrRefCount(agg->obj); - if (agg->var) Tcl_DecrRefCount(agg->var); + if (rc && agg->copied) + Tcl_DecrRefCount(agg->obj); } int pat_hb(Tcl_Interp *ip, Tcl_Obj *obj, HBytes_Value *val) { diff --git a/hbytes/ulongs.c b/hbytes/ulongs.c index f8b8c9e..ac87933 100644 --- a/hbytes/ulongs.c +++ b/hbytes/ulongs.c @@ -290,6 +290,7 @@ static void ulong_t_free(Tcl_Obj *o) { } static void ulong_t_dup(Tcl_Obj *src, Tcl_Obj *dup) { dup->internalRep= src->internalRep; + dup->typePtr= &ulong_type; } static void ulong_t_ustr(Tcl_Obj *o) { -- 2.30.2