Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:21728 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 17036 invoked by uid 1010); 30 Jan 2006 01:14:04 -0000 Delivered-To: ezmlm-scan-internals@lists.php.net Delivered-To: ezmlm-internals@lists.php.net Received: (qmail 17020 invoked from network); 30 Jan 2006 01:14:04 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 30 Jan 2006 01:14:04 -0000 X-Host-Fingerprint: 69.12.155.130 69-12-155-130.dsl.static.sonic.net Linux 2.4/2.6 Received: from ([69.12.155.130:2812] helo=pigeon.alphaweb.net) by pb1.pair.com (ecelerity 2.0 beta r(6323M)) with SMTP id 72/10-11461-B586DD34 for ; Sun, 29 Jan 2006 20:14:03 -0500 Received: from localhost ([127.0.0.1] helo=stumpy) by pigeon.alphaweb.net with smtp (Exim 4.10) id 1F3M2b-0003Wv-00; Sun, 29 Jan 2006 15:33:05 -0800 Message-ID: <000c01c62534$d48aef80$7d051fac@stumpy> To: "Stefan Esser" Cc: References: <43DD2D20.5010001@php.net> Date: Sun, 29 Jan 2006 16:33:43 -0800 MIME-Version: 1.0 Content-Type: text/plain; format=flowed; charset="iso-8859-1"; reply-type=original Content-Transfer-Encoding: 7bit X-Priority: 3 X-MSMail-Priority: Normal X-Mailer: Microsoft Outlook Express 6.00.2900.2180 X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2180 Subject: Re: zend_hash.c fishy code From: pollita@php.net ("Sara Golemon") > I wonder If I am completely missing the point, but the following piece > of code seems fishy to me: > > ZEND_API int zend_hash_del_key_or_index(HashTable *ht, char *arKey, uint > nKeyLength, ulong h, int flag) > { > uint nIndex; > Bucket *p; > > ... > > while (p != NULL) { > if ((p->h == h) && ((p->nKeyLength == 0) || /* Numeric > index */ > ((p->nKeyLength == nKeyLength) && > (!memcmp(p->arKey, arKey, nKeyLength))))) { > HANDLE_BLOCK_INTERRUPTIONS(); > ... > > If I am not completely mistaken this means: If this is a bucket with a > numeric index with the hash value of the key we want to delete, then > delete it, even when we wanted to delete a key with a string as index. > There's a fairly important bit in that first ...: if (flag == HASH_DEL_KEY) { h = zend_inline_hash_func(arKey, nKeyLength); } When deleting a numeric index nKeyLength is passed as zero and h contains the numeric index so this if only matches when p->h == h and p->nKeyLength == 0 (indicating a numericly keyed bucket). When deleting a string index, nKeyLength is non-zero and h as passed is unimportant since it's overridden with the actual hash of arKey and nKeyLength. The if then only evaluates true when the bucket hash matches the computed hash and the real key data in the bucket matches the real key data passed. Yes, comparing p->h to h seems unnecessary since p->arKey is being compared to arKey anyway, but that seemingly redundant comparison saves a more costly memcmp() when the hashes differ. -Sara