]> granicus.if.org Git - php/commitdiff
MFH: - Fixed bug #26267 (gmp_random() leaks memory and does not produce random numbers)
authorfoobar <sniper@php.net>
Wed, 19 Nov 2003 04:44:24 +0000 (04:44 +0000)
committerfoobar <sniper@php.net>
Wed, 19 Nov 2003 04:44:24 +0000 (04:44 +0000)
NEWS
ext/gmp/config.m4
ext/gmp/gmp.c
ext/gmp/php_gmp.h

diff --git a/NEWS b/NEWS
index a98f841989c367d2b077cf3299e37db4f2697e6e..9f99f4d3a20db0e689fd8774a7ff9b814100d498 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -3,6 +3,8 @@ PHP 4                                                                      NEWS
 ?? ??? 2003, Version 4.3.5
 - Fixed header handler in NSAPI SAPI module (header->replace was ignored,
   send_default_content_type now sends value from php.ini). (Uwe Schindler)
+- Fixed bug #26267 (gmp_random() leaks memory and does not produce random
+  numbers). (Jani)
 - Fixed bug #26253 (ext/tokenizer: build as shared extension fails). (Jani)
 - Fixed bug #26235 (yp_first/yp_next do not specify correct key length). (Ilia)
 - Fixed bug #26216 ("getimagesize(): stream does not support seeking" when
index 39e1bb24f939f9052321f899ca734a63bd96970c..aeb7edbd551ebc7dfb5c46a9bd1909769b8df867 100644 (file)
@@ -3,7 +3,7 @@ dnl $Id$
 dnl
 
 PHP_ARG_WITH(gmp, for GNU MP support,
-[  --with-gmp              Include GNU MP support])
+[  --with-gmp[=DIR]        Include GNU MP support])
 
 if test "$PHP_GMP" != "no"; then
 
@@ -14,6 +14,18 @@ if test "$PHP_GMP" != "no"; then
   if test -z "$GMP_DIR"; then
     AC_MSG_ERROR(Unable to locate gmp.h)
   fi
+  PHP_CHECK_LIBRARY(gmp, __gmp_randinit_lc_2exp_size,
+  [],[
+    PHP_CHECK_LIBRARY(gmp, gmp_randinit_lc_2exp_size,
+    [],[
+      AC_MSG_ERROR([GNU MP Library version 4.1.2 or greater required.])
+    ],[
+      -L$GMP_DIR/lib
+    ])
+  ],[
+    -L$GMP_DIR/lib
+  ])
 
   PHP_ADD_LIBRARY_WITH_PATH(gmp, $GMP_DIR/lib, GMP_SHARED_LIBADD)
   PHP_ADD_INCLUDE($GMP_DIR/include)
index 717ed221df9010833994ae675d7978763337f92b..ce5fa0af88a097d51ffcad780028d57f87ce3edb 100644 (file)
 #if HAVE_GMP
 
 #include <gmp.h>
-/* If you declare any globals in php_gmp.h uncomment this:
-ZEND_DECLARE_MODULE_GLOBALS(gmp)
-*/
+
+/* Needed for gmp_random() */
+#include "ext/standard/php_rand.h"
+#include "ext/standard/php_lcg.h"
+#include <gmp-mparam.h>
+#define GMP_ABS(x) ((x) >= 0 ? (x) : -(x))
 
 /* True global resources - no need for thread safety here */
 static int le_gmp;
@@ -92,13 +95,15 @@ zend_module_entry gmp_module_entry = {
        ZEND_MODULE_STARTUP_N(gmp),
        ZEND_MODULE_SHUTDOWN_N(gmp),
        NULL,
-       NULL,
+       ZEND_MODULE_DEACTIVATE_N(gmp),
        ZEND_MODULE_INFO_N(gmp),
        NO_VERSION_YET,
        STANDARD_MODULE_PROPERTIES
 };
 /* }}} */
 
+ZEND_DECLARE_MODULE_GLOBALS(gmp)
+
 #ifdef COMPILE_DL_GMP
 ZEND_GET_MODULE(gmp)
 #endif
@@ -135,10 +140,20 @@ static void gmp_efree(void *ptr, size_t size)
 }
 /* }}} */
 
+/* {{{ php_gmp_init_globals
+ */
+static void php_gmp_init_globals(zend_gmp_globals *gmp_globals)
+{
+       gmp_globals->rand_initialized = 0;
+}
+/* }}} */
+
 /* {{{ ZEND_MINIT_FUNCTION
  */
 ZEND_MODULE_STARTUP_D(gmp)
 {
+    ZEND_INIT_MODULE_GLOBALS(gmp, php_gmp_init_globals, NULL);
+
        le_gmp = zend_register_list_destructors_ex(_php_gmpnum_free, NULL, GMP_RESOURCE_NAME, module_number);
        REGISTER_LONG_CONSTANT("GMP_ROUND_ZERO", GMP_ROUND_ZERO, CONST_CS | CONST_PERSISTENT);
        REGISTER_LONG_CONSTANT("GMP_ROUND_PLUSINF", GMP_ROUND_PLUSINF, CONST_CS | CONST_PERSISTENT);
@@ -150,6 +165,19 @@ ZEND_MODULE_STARTUP_D(gmp)
 }
 /* }}} */
 
+/* {{{ ZEND_RSHUTDOWN_FUNCTION
+ */
+ZEND_MODULE_DEACTIVATE_D(gmp)
+{
+       if (GMPG(rand_initialized)) {
+               gmp_randclear(GMPG(rand_state));
+               GMPG(rand_initialized) = 0;
+       }
+
+       return SUCCESS;
+}
+/* }}} */
+
 /* {{{ ZEND_MSHUTDOWN_FUNCTION
  */
 ZEND_MODULE_SHUTDOWN_D(gmp)
@@ -1041,7 +1069,17 @@ ZEND_FUNCTION(gmp_random)
        }
 
        INIT_GMP_NUM(gmpnum_result);
-       mpz_random(*gmpnum_result, limiter);
+
+       if (!GMPG(rand_initialized)) {
+               /* Initialize */
+               gmp_randinit_lc_2exp_size(GMPG(rand_state), 32L);
+
+               /* Seed */
+               gmp_randseed_ui(GMPG(rand_state), GENERATE_SEED());
+
+               GMPG(rand_initialized) = 1;
+       }
+       mpz_urandomb(*gmpnum_result, GMPG(rand_state), GMP_ABS (limiter) * BITS_PER_MP_LIMB);
 
        ZEND_REGISTER_RESOURCE(return_value, gmpnum_result, le_gmp);
 }
index c6fdb3b6e1f88f80af28f448e1b9e5d45e182bab..8260e6a379043252e560fd863c1efc24a95e730e 100644 (file)
 #ifndef PHP_GMP_H
 #define PHP_GMP_H
 
-/* You should tweak config.m4 so this symbol (or some else suitable)
-   gets defined.
-*/
 #if HAVE_GMP
 
+#include <gmp.h>
+
 extern zend_module_entry gmp_module_entry;
 #define phpext_gmp_ptr &gmp_module_entry
 
@@ -35,6 +34,7 @@ extern zend_module_entry gmp_module_entry;
 
 ZEND_MODULE_STARTUP_D(gmp);
 ZEND_MODULE_SHUTDOWN_D(gmp);
+ZEND_MODULE_DEACTIVATE_D(gmp);
 ZEND_MODULE_INFO_D(gmp);
 
 ZEND_FUNCTION(gmp_init);
@@ -76,24 +76,13 @@ ZEND_FUNCTION(gmp_scan1);
 ZEND_FUNCTION(gmp_popcount);
 ZEND_FUNCTION(gmp_hamdist);
 
-/* 
-       Declare any global variables you may need between the BEGIN
-       and END macros here:     
-
 ZEND_BEGIN_MODULE_GLOBALS(gmp)
-       int global_variable;
+       zend_bool rand_initialized;
+       gmp_randstate_t rand_state;
 ZEND_END_MODULE_GLOBALS(gmp)
-*/
-
-/* In every function that needs to use variables in php_gmp_globals,
-   do call GMPLS_FETCH(); after declaring other variables used by
-   that function, and always refer to them as GMPG(variable).
-   You are encouraged to rename these macros something shorter, see
-   examples in any other php module directory.
-*/
 
 #ifdef ZTS
-#define GMPG(v) TSRMG(gmp_globals_id, php_gmp_globals *, v)
+#define GMPG(v) TSRMG(gmp_globals_id, zend_gmp_globals *, v)
 #else
 #define GMPG(v) (gmp_globals.v)
 #endif