diff options
author | Sebastian Gniazdowski <psprint@zdharma.org> | 2017-05-24 16:07:23 +0200 |
---|---|---|
committer | Peter Stephenson <pws@zsh.org> | 2017-05-24 15:55:42 +0100 |
commit | 62c416915b1bee6d7ef9dc87f6009907748f2087 (patch) | |
tree | 70fba54f3213112147baa0dde1edb88a34c169d5 /Src/Modules/db_gdbm.c | |
parent | 135075e48c6c2789bd8bae0a643961c0c2361dfc (diff) | |
download | zsh-62c416915b1bee6d7ef9dc87f6009907748f2087.tar.gz zsh-62c416915b1bee6d7ef9dc87f6009907748f2087.tar.xz zsh-62c416915b1bee6d7ef9dc87f6009907748f2087.zip |
41146: careul in GDBM freeing strings with embedded nulls
Diffstat (limited to 'Src/Modules/db_gdbm.c')
-rw-r--r-- | Src/Modules/db_gdbm.c | 39 |
1 files changed, 29 insertions, 10 deletions
diff --git a/Src/Modules/db_gdbm.c b/Src/Modules/db_gdbm.c index 0a28a0740..35254b68c 100644 --- a/Src/Modules/db_gdbm.c +++ b/Src/Modules/db_gdbm.c @@ -41,7 +41,8 @@ static Param createhash( char *name, int flags ); static int append_tied_name( const char *name ); static int remove_tied_name( const char *name ); -char *unmetafy_zalloc(const char *to_copy, int *new_len); +static char *unmetafy_zalloc(const char *to_copy, int *new_len); +static void set_length(char *buf, int size); /* * Make sure we have all the bits I'm using for memory mapping, otherwise @@ -320,13 +321,15 @@ gdbmgetfn(Param pm) pm->u.str = metafy(content.dptr, content.dsize, META_DUP); /* Free key, restoring its original length */ + set_length(umkey, umlen); zsfree(umkey); /* Can return pointer, correctly saved inside hash */ return pm->u.str; } - /* Free key */ + /* Free key, restoring its original length */ + set_length(umkey, umlen); zsfree(umkey); /* Can this be "" ? */ @@ -375,12 +378,14 @@ gdbmsetfn(Param pm, char *val) (void)gdbm_store(dbf, key, content, GDBM_REPLACE); /* Free */ + set_length(umval, umlen); zsfree(umval); } else { (void)gdbm_delete(dbf, key); } /* Free key */ + set_length(umkey, key.dsize); zsfree(umkey); } } @@ -519,10 +524,12 @@ gdbmhashsetfn(Param pm, HashTable ht) content.dsize = umlen; (void)gdbm_store(dbf, key, content, GDBM_REPLACE); - /* Free - thanks to unmetafy_zalloc size of - * the strings is exact zalloc size - can - * pass to zsfree */ + /* Free - unmetafy_zalloc allocates exact required + * space, however unmetafied string can have zeros + * in content, so we must first fill with non-0 bytes */ + set_length(umval, content.dsize); zsfree(umval); + set_length(umkey, key.dsize); zsfree(umkey); unqueue_signals(); @@ -577,10 +584,6 @@ gdbmhashunsetfn(Param pm, UNUSED(int exp)) pm->node.flags |= PM_UNSET; } -#else -# error no gdbm -#endif /* have gdbm */ - static struct features module_features = { bintab, sizeof(bintab)/sizeof(*bintab), NULL, 0, @@ -746,7 +749,7 @@ static int remove_tied_name( const char *name ) { * * No zsfree()-confusing string will be produced. */ -char *unmetafy_zalloc(const char *to_copy, int *new_len) { +static char *unmetafy_zalloc(const char *to_copy, int *new_len) { char *work, *to_return; int my_new_len = 0; @@ -767,3 +770,19 @@ char *unmetafy_zalloc(const char *to_copy, int *new_len) { return to_return; } + +/* + * For zsh-allocator, rest of Zsh seems to use + * free() instead of zsfree(), and such length + * restoration causes slowdown, but all is this + * way strict - correct */ +static void set_length(char *buf, int size) { + buf[size]='\0'; + while ( -- size >= 0 ) { + buf[size]=' '; + } +} + +#else +# error no gdbm +#endif /* have gdbm */ |