php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #35014 array_product() is broken
Submitted: 2005-10-29 08:48 UTC Modified: 2005-10-30 14:47 UTC
From: arpad at rajeczy dot com Assigned:
Status: Closed Package: Arrays related
PHP Version: 5CVS-2005-10-29 (CVS) OS: linux 2.6.13 x86_64
Private report: No CVE-ID:
 [2005-10-29 08:48 UTC] arpad at rajeczy dot com
Description:
------------
The array_product() function is completely broken, it  
returns 0 for all valid input and when the input is an  
empty array. 
  
Having looked at ext/standard/array.c, array_product()  
seems to be a straight copy of array_sum(), but with '+'  
replaced by  '*'. As in array_sum(), the initial  
return_value is 0, but because the elements are multiplied  
with return_value rather than added to it, the result is  
always 0.  

Reproduce code:
---------------
<pre><?php

$tests = array(
	'foo',
	array(),
	array(0),
	array(3),
	array(3, 3),
	array(0.5, 2),
	array(99999999, 99999999)
);

foreach ($tests as $v) {
	echo 'testing: (', (is_array($v) ? implode(' * ', $v) : $v), ")\n\tresult: ";
	var_dump(array_product($v));
	echo "\n\n"; 
}

?></pre>

Expected result:
----------------
testing: (foo) 
        result:  
 
Warning:  array_product() [function.array-product]: The 
argument should be an array 
in /usr/local/apache2/htdocs/a/t.php on line 14 
 
NULL 
 
 
testing: () 
        result:  
 
Warning:  array_product() [function.array-product]: Array 
must contain at least one element 
in /usr/local/apache2/htdocs/a/t.php on line 14 
 
NULL 
 
 
testing: (0) 
        result: int(0) 
 
 
testing: (3) 
        result: int(3) 
 
 
testing: (3 * 3) 
        result: int(9) 
 
 
testing: (0.5 * 2) 
        result: float(1) 
 
 
testing: (9999999 * 9999999) 
        result: int(99999980000001) 

Actual result:
--------------
testing: (foo) 
        result:  
 
Warning:  array_product() [function.array-product]: The 
argument should be an array 
in /usr/local/apache2/htdocs/a/t.php on line 14 
 
NULL 
 
 
testing: () 
        result: int(0) 
 
 
testing: (0) 
        result: int(0) 
 
 
testing: (3) 
        result: int(0) 
 
 
testing: (3 * 3) 
        result: int(0) 
 
 
testing: (0.5 * 2) 
        result: float(0) 
 
 
testing: (99999999 * 99999999) 
        result: int(0) 

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2005-10-29 08:56 UTC] arpad at rajeczy dot com
The easy fix of changing the initial return_value to 1 
means that the function returns 1 for an empty array. I 
think raising an error as in max() makes more sense, so 
I've also included that in the following patch. 
 
Index: ext/standard/array.c 
=================================================================== 
RCS file: /repository/php-src/ext/standard/array.c,v 
retrieving revision 1.308.2.10 
diff -u -u -b -B -r1.308.2.10 array.c 
--- ext/standard/array.c        28 Oct 2005 09:57:35 -0000      
1.308.2.10 
+++ ext/standard/array.c        29 Oct 2005 06:04:22 -0000 
@@ -3997,7 +3997,12 @@ 
                return; 
        } 
 
-       ZVAL_LONG(return_value, 0); 
+       if (zend_hash_num_elements(Z_ARRVAL_PP(input)) == 
0) { 
+               php_error_docref(NULL TSRMLS_CC, 
E_WARNING, "Array must contain at least one element"); 
+               return; 
+       } 
+ 
+       ZVAL_LONG(return_value, 1); 
 
        for 
(zend_hash_internal_pointer_reset_ex(Z_ARRVAL_PP(input), 
&pos); 
                 
zend_hash_get_current_data_ex(Z_ARRVAL_PP(input), (void 
**)&entry, &pos) == SUCCESS;
 [2005-10-30 14:47 UTC] iliaa@php.net
This bug has been fixed in CVS.

Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.
 
Thank you for the report, and for helping us make PHP better.


 
PHP Copyright © 2001-2014 The PHP Group
All rights reserved.
Last updated: Sat Apr 19 22:02:16 2014 UTC