Skip to content

Commit e6d996d

Browse files
author
Jeroen van Wolffelaar
committed
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)
1 parent 2235479 commit e6d996d

File tree

8 files changed

+81
-20
lines changed

8 files changed

+81
-20
lines changed

ext/standard/basic_functions.c

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
#include "php_ini.h"
2626
#include "internal_functions_registry.h"
2727
#include "php_standard.h"
28-
#include "php_math.h"
2928
#include "php_incomplete_class.h"
3029
#include "ext/standard/info.h"
3130
#include "zend_operators.h"
@@ -868,17 +867,14 @@ PHP_RINIT_FUNCTION(basic)
868867
#endif
869868
BG(user_shutdown_function_names)=NULL;
870869

871-
#if HAVE_CRYPT
872-
PHP_RINIT(crypt)(INIT_FUNC_ARGS_PASSTHRU);
873-
#endif
874-
875870
#ifndef ZTS
876871
PHP_RINIT(lcg)(INIT_FUNC_ARGS_PASSTHRU);
877872
#endif
878873

879874
PHP_RINIT(filestat)(INIT_FUNC_ARGS_PASSTHRU);
880875
PHP_RINIT(syslog)(INIT_FUNC_ARGS_PASSTHRU);
881876
PHP_RINIT(dir)(INIT_FUNC_ARGS_PASSTHRU);
877+
PHP_RINIT(rand)(INIT_FUNC_ARGS_PASSTHRU);
882878

883879
#ifdef TRANS_SID
884880
if (BG(use_trans_sid)) {

ext/standard/basic_functions.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,10 @@ typedef struct {
171171
struct stat lsb;
172172

173173
/* rand.c */
174+
int rand_generator; /* current ini-setting */
175+
int rand_generator_current; /* current (by overriding by [mt_]srand) */
176+
177+
/* rand_mt.c */
174178
php_uint32 state[MT_N+1]; /* state vector + 1 extra to not violate ANSI C */
175179
php_uint32 *next; /* next random value is computed from here */
176180
int left; /* can *next++ this many times before reloading */

ext/standard/crypt.c

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,6 @@ extern char *crypt(char *__key, char *__salt);
8989

9090
#define PHP_CRYPT_RAND php_rand()
9191

92-
static int php_crypt_rand_seeded=0;
93-
9492
PHP_MINIT_FUNCTION(crypt)
9593
{
9694
REGISTER_LONG_CONSTANT("CRYPT_SALT_LENGTH", PHP_MAX_SALT_LEN, CONST_CS | CONST_PERSISTENT);
@@ -103,17 +101,6 @@ PHP_MINIT_FUNCTION(crypt)
103101
}
104102

105103

106-
PHP_RINIT_FUNCTION(crypt)
107-
{
108-
if(!php_crypt_rand_seeded) {
109-
/* FIXME (jeroen): temporary fix for RAND_REDESIGN */
110-
php_srand_sys(time(0) * getpid() * (php_combined_lcg(TSRMLS_C) * 10000.0));
111-
php_crypt_rand_seeded=1;
112-
}
113-
return SUCCESS;
114-
}
115-
116-
117104
static unsigned char itoa64[] = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
118105

119106
static void php_to64(char *s, long v, int n) {

ext/standard/lcg.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,11 @@ static int php_lcg_initialized = 0;
4242
* The function combines two CGs with periods of
4343
* 2^31 - 85 and 2^31 - 249. The period of this function
4444
* is equal to the product of both primes.
45+
*
46+
* There are only about 65k distinct starting values, that's
47+
* not much... If PHP is running as CGI, randomness is quite bad.
48+
* If it is run as a module, it's long-livin', so no problem in that
49+
* case.
4550
*/
4651

4752
#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)
103108
* c-basic-offset: 4
104109
* End:
105110
* vim600: sw=4 ts=4 tw=78 fdm=marker
106-
* vim<600: sw=4 ts=4 tw=78
111+
* vim<600: sw=8 ts=8 tw=78
107112
*/

ext/standard/php_crypt.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
PHP_FUNCTION(crypt);
2727
#if HAVE_CRYPT
2828
PHP_MINIT_FUNCTION(crypt);
29-
PHP_RINIT_FUNCTION(crypt);
3029
#endif
3130

3231
#endif

ext/standard/php_rand.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,14 @@ void php_srand_mt(long seed TSRMLS_DC);
115115
/* Define random generator constants */
116116
#define RAND_SYS 1
117117
#define RAND_MT 2
118+
#define RAND_LCG 3
119+
#define RAND_SYS_STR "system"
120+
#define RAND_MT_STR "mt"
121+
#define RAND_LCG_STR "lcg"
122+
123+
#define RAND_DEFAULT RAND_MT
124+
#define RAND_DEFAULT_STR RAND_MT_STR
125+
118126

119127
/* BC */
120128
#define PHP_RAND_MAX php_randmax()

ext/standard/php_standard.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
#include "basic_functions.h"
2222
#include "php_math.h"
23+
#include "php_rand.h"
2324
#include "php_string.h"
2425
#include "base64.h"
2526
#include "php_dir.h"

ext/standard/rand.c

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,74 @@
2424
#include "php.h"
2525
#include "php_math.h"
2626
#include "php_rand.h"
27+
#include "php_ini.h"
2728

2829
#include "zend_execute.h"
2930

3031
#include "basic_functions.h"
3132

3233
/* See php_rand.h for information about layout */
3334

35+
#define SRAND_A_RANDOM_SEED (time(0) * getpid() * (php_combined_lcg(TSRMLS_C) * 10000.0)) /* something with microtime? */
36+
37+
/* TODO: check that this function is called on the start of each script
38+
* execution: not more often, not less often.
39+
*
40+
* Note that system rand is inherently thread-unsafe: A different thread can
41+
* always eat up some rand()'s, and thus nuking your expected sequence.
42+
* Another reason to use MT...
43+
*/
44+
PHP_RINIT_FUNCTION(rand)
45+
{
46+
/* seed all number-generators */
47+
/* FIXME: or seed relevant numgen on init/update ini-entry? */
48+
php_srand_sys(SRAND_A_RANDOM_SEED);
49+
php_srand_mt(SRAND_A_RANDOM_SEED);
50+
}
51+
52+
/* INI */
53+
static int randgen_str_to_int(char *str, int strlen)
54+
{
55+
/* manually check all cases, or some loop to automate this
56+
* kind of stuff, so that a new random number generator
57+
* can be added more easily?
58+
*
59+
* --jeroen
60+
*/
61+
if (!strcasecmp(str,RAND_SYS_STR)) {
62+
return RAND_SYS;
63+
} else if (!strcasecmp(str,RAND_MT_STR)) {
64+
return RAND_MT;
65+
} else if (!strcasecmp(str,RAND_LCG_STR)) {
66+
return RAND_LCG;
67+
}
68+
return 0; /* FIXME: include that f*** .h that has FALSE */
69+
}
70+
71+
/* FIXME: check that this is called on initial ini-parsing too */
72+
/* FIXME: what if no ini-entry was present? */
73+
static PHP_INI_MH(OnUpdateRandGen)
74+
{
75+
/* Set BG(rand_generator) to the correct integer value indicating
76+
* ini-setting */
77+
BG(rand_generator) = randgen_str_to_int(new_value, new_value_length);
78+
if (!BG(rand_generator)) {
79+
/* FIXME: is this possible? What happens if this occurs during
80+
* ini-parsing at startup? */
81+
php_error(E_WARNING,"Invalid value for random_number_generator: \"%s\"", new_value);
82+
/* Fallback: */
83+
BG(rand_generator) = RAND_DEFAULT;
84+
}
85+
#ifdef DEBUG_RAND
86+
printf("\nRAND-INI updated: %d\n",BG(rand_generator));
87+
#endif
88+
return SUCCESS;
89+
}
90+
91+
PHP_INI_BEGIN()
92+
PHP_INI_ENTRY("random_number_generator", RAND_DEFAULT_STR, PHP_INI_ALL, OnUpdateRandGen)
93+
PHP_INI_END()
94+
3495
/* srand */
3596

3697
/* {{{ PHPAPI void php_srand(void) */

0 commit comments

Comments
 (0)