summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeroen van Wolffelaar <jeroen@php.net>2001-08-24 23:47:27 +0000
committerJeroen van Wolffelaar <jeroen@php.net>2001-08-24 23:47:27 +0000
commite6d996d41c30a7d4c93393b61ef1221ac47385b8 (patch)
treec8ca0fbc25ef0c1e5e3d03c25d379d9ab9d5285f
parent22354791110bab54ed370abac66cf69edd961e80 (diff)
downloadphp-git-e6d996d41c30a7d4c93393b61ef1221ac47385b8.tar.gz
Implement (not yet totally complete) INI-logic for rand.
Seed random generators on script execution start (was already done in some configurations by crypt, removed that)
-rw-r--r--ext/standard/basic_functions.c6
-rw-r--r--ext/standard/basic_functions.h4
-rw-r--r--ext/standard/crypt.c13
-rw-r--r--ext/standard/lcg.c7
-rw-r--r--ext/standard/php_crypt.h1
-rw-r--r--ext/standard/php_rand.h8
-rw-r--r--ext/standard/php_standard.h1
-rw-r--r--ext/standard/rand.c61
8 files changed, 81 insertions, 20 deletions
diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c
index dd3487e567..59ef384aa2 100644
--- a/ext/standard/basic_functions.c
+++ b/ext/standard/basic_functions.c
@@ -25,7 +25,6 @@
#include "php_ini.h"
#include "internal_functions_registry.h"
#include "php_standard.h"
-#include "php_math.h"
#include "php_incomplete_class.h"
#include "ext/standard/info.h"
#include "zend_operators.h"
@@ -868,10 +867,6 @@ PHP_RINIT_FUNCTION(basic)
#endif
BG(user_shutdown_function_names)=NULL;
-#if HAVE_CRYPT
- PHP_RINIT(crypt)(INIT_FUNC_ARGS_PASSTHRU);
-#endif
-
#ifndef ZTS
PHP_RINIT(lcg)(INIT_FUNC_ARGS_PASSTHRU);
#endif
@@ -879,6 +874,7 @@ PHP_RINIT_FUNCTION(basic)
PHP_RINIT(filestat)(INIT_FUNC_ARGS_PASSTHRU);
PHP_RINIT(syslog)(INIT_FUNC_ARGS_PASSTHRU);
PHP_RINIT(dir)(INIT_FUNC_ARGS_PASSTHRU);
+ PHP_RINIT(rand)(INIT_FUNC_ARGS_PASSTHRU);
#ifdef TRANS_SID
if (BG(use_trans_sid)) {
diff --git a/ext/standard/basic_functions.h b/ext/standard/basic_functions.h
index 6001628b66..38e7a10c72 100644
--- a/ext/standard/basic_functions.h
+++ b/ext/standard/basic_functions.h
@@ -171,6 +171,10 @@ typedef struct {
struct stat lsb;
/* rand.c */
+ int rand_generator; /* current ini-setting */
+ int rand_generator_current; /* current (by overriding by [mt_]srand) */
+
+ /* rand_mt.c */
php_uint32 state[MT_N+1]; /* state vector + 1 extra to not violate ANSI C */
php_uint32 *next; /* next random value is computed from here */
int left; /* can *next++ this many times before reloading */
diff --git a/ext/standard/crypt.c b/ext/standard/crypt.c
index 5489f01a75..bdd085b5d3 100644
--- a/ext/standard/crypt.c
+++ b/ext/standard/crypt.c
@@ -89,8 +89,6 @@ extern char *crypt(char *__key, char *__salt);
#define PHP_CRYPT_RAND php_rand()
-static int php_crypt_rand_seeded=0;
-
PHP_MINIT_FUNCTION(crypt)
{
REGISTER_LONG_CONSTANT("CRYPT_SALT_LENGTH", PHP_MAX_SALT_LEN, CONST_CS | CONST_PERSISTENT);
@@ -103,17 +101,6 @@ PHP_MINIT_FUNCTION(crypt)
}
-PHP_RINIT_FUNCTION(crypt)
-{
- if(!php_crypt_rand_seeded) {
- /* FIXME (jeroen): temporary fix for RAND_REDESIGN */
- php_srand_sys(time(0) * getpid() * (php_combined_lcg(TSRMLS_C) * 10000.0));
- php_crypt_rand_seeded=1;
- }
- return SUCCESS;
-}
-
-
static unsigned char itoa64[] = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
static void php_to64(char *s, long v, int n) {
diff --git a/ext/standard/lcg.c b/ext/standard/lcg.c
index 7ae45a0ef0..f211317d73 100644
--- a/ext/standard/lcg.c
+++ b/ext/standard/lcg.c
@@ -42,6 +42,11 @@ static int php_lcg_initialized = 0;
* The function combines two CGs with periods of
* 2^31 - 85 and 2^31 - 249. The period of this function
* is equal to the product of both primes.
+ *
+ * There are only about 65k distinct starting values, that's
+ * not much... If PHP is running as CGI, randomness is quite bad.
+ * If it is run as a module, it's long-livin', so no problem in that
+ * case.
*/
#define MODMULT(a, b, c, m, s) q = s/a;s=b*(s-a*q)-c*q;if(s<0)s+=m
@@ -103,5 +108,5 @@ PHP_FUNCTION(lcg_value)
* c-basic-offset: 4
* End:
* vim600: sw=4 ts=4 tw=78 fdm=marker
- * vim<600: sw=4 ts=4 tw=78
+ * vim<600: sw=8 ts=8 tw=78
*/
diff --git a/ext/standard/php_crypt.h b/ext/standard/php_crypt.h
index b4b04bbd51..a977d61055 100644
--- a/ext/standard/php_crypt.h
+++ b/ext/standard/php_crypt.h
@@ -26,7 +26,6 @@
PHP_FUNCTION(crypt);
#if HAVE_CRYPT
PHP_MINIT_FUNCTION(crypt);
-PHP_RINIT_FUNCTION(crypt);
#endif
#endif
diff --git a/ext/standard/php_rand.h b/ext/standard/php_rand.h
index 0d20f84225..9088588f2e 100644
--- a/ext/standard/php_rand.h
+++ b/ext/standard/php_rand.h
@@ -115,6 +115,14 @@ void php_srand_mt(long seed TSRMLS_DC);
/* Define random generator constants */
#define RAND_SYS 1
#define RAND_MT 2
+#define RAND_LCG 3
+#define RAND_SYS_STR "system"
+#define RAND_MT_STR "mt"
+#define RAND_LCG_STR "lcg"
+
+#define RAND_DEFAULT RAND_MT
+#define RAND_DEFAULT_STR RAND_MT_STR
+
/* BC */
#define PHP_RAND_MAX php_randmax()
diff --git a/ext/standard/php_standard.h b/ext/standard/php_standard.h
index 536c13807e..2a05b61be7 100644
--- a/ext/standard/php_standard.h
+++ b/ext/standard/php_standard.h
@@ -20,6 +20,7 @@
#include "basic_functions.h"
#include "php_math.h"
+#include "php_rand.h"
#include "php_string.h"
#include "base64.h"
#include "php_dir.h"
diff --git a/ext/standard/rand.c b/ext/standard/rand.c
index 5e1c39fbdc..72736cc4b7 100644
--- a/ext/standard/rand.c
+++ b/ext/standard/rand.c
@@ -24,6 +24,7 @@
#include "php.h"
#include "php_math.h"
#include "php_rand.h"
+#include "php_ini.h"
#include "zend_execute.h"
@@ -31,6 +32,66 @@
/* See php_rand.h for information about layout */
+#define SRAND_A_RANDOM_SEED (time(0) * getpid() * (php_combined_lcg(TSRMLS_C) * 10000.0)) /* something with microtime? */
+
+/* TODO: check that this function is called on the start of each script
+ * execution: not more often, not less often.
+ *
+ * Note that system rand is inherently thread-unsafe: A different thread can
+ * always eat up some rand()'s, and thus nuking your expected sequence.
+ * Another reason to use MT...
+ */
+PHP_RINIT_FUNCTION(rand)
+{
+ /* seed all number-generators */
+ /* FIXME: or seed relevant numgen on init/update ini-entry? */
+ php_srand_sys(SRAND_A_RANDOM_SEED);
+ php_srand_mt(SRAND_A_RANDOM_SEED);
+}
+
+/* INI */
+static int randgen_str_to_int(char *str, int strlen)
+{
+ /* manually check all cases, or some loop to automate this
+ * kind of stuff, so that a new random number generator
+ * can be added more easily?
+ *
+ * --jeroen
+ */
+ if (!strcasecmp(str,RAND_SYS_STR)) {
+ return RAND_SYS;
+ } else if (!strcasecmp(str,RAND_MT_STR)) {
+ return RAND_MT;
+ } else if (!strcasecmp(str,RAND_LCG_STR)) {
+ return RAND_LCG;
+ }
+ return 0; /* FIXME: include that f*** .h that has FALSE */
+}
+
+/* FIXME: check that this is called on initial ini-parsing too */
+/* FIXME: what if no ini-entry was present? */
+static PHP_INI_MH(OnUpdateRandGen)
+{
+ /* Set BG(rand_generator) to the correct integer value indicating
+ * ini-setting */
+ BG(rand_generator) = randgen_str_to_int(new_value, new_value_length);
+ if (!BG(rand_generator)) {
+ /* FIXME: is this possible? What happens if this occurs during
+ * ini-parsing at startup? */
+ php_error(E_WARNING,"Invalid value for random_number_generator: \"%s\"", new_value);
+ /* Fallback: */
+ BG(rand_generator) = RAND_DEFAULT;
+ }
+#ifdef DEBUG_RAND
+ printf("\nRAND-INI updated: %d\n",BG(rand_generator));
+#endif
+ return SUCCESS;
+}
+
+PHP_INI_BEGIN()
+ PHP_INI_ENTRY("random_number_generator", RAND_DEFAULT_STR, PHP_INI_ALL, OnUpdateRandGen)
+PHP_INI_END()
+
/* srand */
/* {{{ PHPAPI void php_srand(void) */