Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 18 Feb 2003 04:41:12 +0100 (CET)
From:      Maxlor <mail@maxlor.com>
To:        FreeBSD-gnats-submit@FreeBSD.org
Subject:   ports/48406: missing initialization bug in /usr/ports/devel/libhash
Message-ID:  <20030218034112.A7E5012CCE0@maxlor.mine.nu>

next in thread | raw e-mail | index | archive | help

>Number:         48406
>Category:       ports
>Synopsis:       missing initialization bug in /usr/ports/devel/libhash
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-ports-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon Feb 17 19:50:02 PST 2003
>Closed-Date:
>Last-Modified:
>Originator:     Maxlor
>Release:        FreeBSD 5.0-RELEASE-p1 i386
>Organization:
>Environment:
System: FreeBSD merlin 5.0-RELEASE-p1 FreeBSD 5.0-RELEASE-p1 #0: Sun Feb 16 04:23:52 CET 2003 maxlor@merlin:/usr/obj/usr/src/sys/MERLIN i386

>Description:
	The function hash_hash_string in hash.c uses the variable
	"u_int32_t hash_value", but does not initialize it before
	it is read for the first time. Therefore the function is
	broken and yields random results.

>How-To-Repeat:
	The code below needs to be compiled as follows:

	 gcc -g -I/usr/local/include -L/usr/local/lib -o hashtest_str hashtest_str.c -lhash

	When run with the corrected libhash, it will store a value
	into a hash using a string key, then retrieve it, then list
	all keys in the hash (and therefore retrieve it a second time).
	When run with a broken libhash, it will either not be able
	to retrieve the value, or the retrieved key will be random.

	----- CODE START -----
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include <hash.h>
#include <dirent.h>
#include <errno.h>

#define NUMBEROFBUCKETS 40000

int main(int argc, char *argv[]) {
        hash h;
        struct hash_iterator it;
        char key[] = "abcd";
        int value = 101;
        char **pkey;
        int *pvalue;
        int i;


        pkey = malloc(sizeof(char *));
        if (pkey == NULL) {
                printf("malloc 1 failed\n");
                exit(1);
        }

        pvalue = malloc(sizeof(int));
        if (pvalue == NULL) {
                printf("malloc 2 failed\n");
                exit(1);
        }

        *pvalue = 0;

        printf("Errors: \n");
        printf("  %i = ENOENT = key doesn't exist\n", ENOENT);
        printf("  %i = ENOMEM = no memory\n", ENOMEM);

        if (! hash_initialise(&h, NUMBEROFBUCKETS, hash_hash_string,
                              hash_compare_string, hash_copy_string,
                              free, free)) {
                printf("Error: initialise\n");
                exit(1);
        }

        printf("Trying to insert key into hash:\n");

        if (! hash_insert(&h, key, (void*)value)) {
                printf("  Error: insert\n");
                exit(1);
        } else {
                printf("  Inserted: key = %s, value = %i\n", key, value);
        }

        printf("\n");

        printf("Trying to retrieve the same key from hash:\n");

        if (! hash_retrieve(&h, key, (void**)pvalue)) {
                printf("  Error: retrieve (%i)\n", errno);
                //exit(1);
        } else {
                printf("  Retrieve: key = %s, value = %i\n", key, *pvalue);
        }

        printf("\n");


        if (!hash_iterator_initialise(&h, &it)) {
                fprintf(stderr, "Error: hash_iterator_initialise failed\n");
                return 1;
        }

        printf("Iterating through all keys in hash:\n");

        while (hash_fetch_next(&h, &it, (void **)pkey, (void**) pvalue)) {
                if (! hash_retrieve(&h, *pkey, (void**)pvalue)) {
                        printf("  Error: retrieve (%i)\n", errno);
                } else {
                        printf("  Retrieve: key = %s, value = %i\n", key, *pvalu
e);
                }
        }

        printf("\nDone\n");

        if (!hash_iterator_deinitialise(&h, &it)) {
                fprintf(stderr, "Error: hash_iterator_deinitialise failed\n");
                return 1;
        }

        return 0;
}
	----- CODE END -----

>	Fix:
	----- DIFF START -----
sh.c.orig Wed Feb 12 04:38:58 2003
--- hash.c      Mon Feb 17 17:03:20 2003
*************** int hash_compare_int(void *key1, void *k
*** 25,31 ****
  }
  
  u_int32_t hash_hash_string(void *key, u_int32_t number_of_buckets) {
!       u_int32_t hash_value;
  
        while (*(char *)key != '\0') {
                hash_value += *(char *)key;
--- 25,31 ----
  }
  
  u_int32_t hash_hash_string(void *key, u_int32_t number_of_buckets) {
!       u_int32_t hash_value = 0;
  
        while (*(char *)key != '\0') {
                hash_value += *(char *)key;
	----- DIFF END -----

>Fix:
>Release-Note:
>Audit-Trail:
>Unformatted:

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-ports-bugs" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20030218034112.A7E5012CCE0>