@@ -157,13 +157,16 @@ static zend_object_handlers random_randomizer_object_handlers;
157
157
158
158
static uint32_t rand_range32 (const php_random_engine_algo * algo , void * state , uint32_t umax ) {
159
159
uint32_t result , limit ;
160
- size_t generated_size = algo -> size (state );
160
+ size_t generated_size ;
161
+
162
+ RANDOM_ENGINE_GENERATE_SIZE (algo , state , result , generated_size );
161
163
162
- result = algo -> generate (state );
163
164
while (generated_size < sizeof (uint32_t )) {
164
- size_t generate_size = algo -> size (state );
165
+ uint32_t ret ;
166
+ size_t generate_size ;
165
167
166
- result = (result << generate_size ) | algo -> generate (state );
168
+ RANDOM_ENGINE_GENERATE_SIZE (algo , state , ret , generate_size );
169
+ result = (result << generate_size ) | ret ;
167
170
168
171
generated_size += generate_size ;
169
172
}
@@ -186,12 +189,14 @@ static uint32_t rand_range32(const php_random_engine_algo *algo, void *state, ui
186
189
187
190
/* Discard numbers over the limit to avoid modulo bias */
188
191
while (UNEXPECTED (result > limit )) {
189
- generated_size = algo -> size (state );
190
- result = algo -> generate (state );
192
+ RANDOM_ENGINE_GENERATE_SIZE (algo , state , result , generated_size );
191
193
while (generated_size < sizeof (uint32_t )) {
192
- size_t generate_size = algo -> size (state );
194
+ uint32_t ret ;
195
+ size_t generate_size ;
196
+
197
+ RANDOM_ENGINE_GENERATE_SIZE (algo , state , ret , generate_size );
193
198
194
- result = (result << generate_size ) | algo -> generate ( state ) ;
199
+ result = (result << generate_size ) | ret ;
195
200
196
201
generated_size += generate_size ;
197
202
}
@@ -203,13 +208,17 @@ static uint32_t rand_range32(const php_random_engine_algo *algo, void *state, ui
203
208
#if ZEND_ULONG_MAX > UINT32_MAX
204
209
static uint64_t rand_range64 (const php_random_engine_algo * algo , void * state , uint64_t umax ) {
205
210
uint64_t result , limit ;
206
- size_t generated_size = algo -> size (state );
211
+ size_t generated_size ;
212
+
213
+ RANDOM_ENGINE_GENERATE_SIZE (algo , state , result , generated_size );
207
214
208
- result = algo -> generate (state );
209
215
while (generated_size < sizeof (uint64_t )) {
210
- size_t generate_size = algo -> size (state );
216
+ uint64_t ret ;
217
+ size_t generate_size ;
218
+
219
+ RANDOM_ENGINE_GENERATE_SIZE (algo , state , ret , generate_size );
211
220
212
- result = (result << generate_size ) | algo -> generate ( state ) ;
221
+ result = (result << generate_size ) | ret ;
213
222
214
223
generated_size += generate_size ;
215
224
}
@@ -232,13 +241,15 @@ static uint64_t rand_range64(const php_random_engine_algo *algo, void *state, ui
232
241
233
242
/* Discard numbers over the limit to avoid modulo bias */
234
243
while (UNEXPECTED (result > limit )) {
235
- generated_size = algo -> size (state );
236
- result = algo -> generate (state );
244
+ RANDOM_ENGINE_GENERATE_SIZE (algo , state , result , generated_size );
237
245
238
246
while (generated_size < sizeof (uint64_t )) {
239
- size_t generate_size = algo -> size (state );
247
+ uint64_t ret ;
248
+ size_t generate_size ;
240
249
241
- result = (result << generate_size ) | algo -> generate (state );
250
+ RANDOM_ENGINE_GENERATE_SIZE (algo , state , ret , generate_size );
251
+
252
+ result = (result << generate_size ) | ret ;
242
253
243
254
generated_size += generate_size ;
244
255
}
@@ -289,7 +300,7 @@ static zend_object *php_random_engine_common_clone_obj(zend_object *old_object)
289
300
290
301
/* XorShift128Plus begin */
291
302
292
- static inline size_t xorshift128plus_size (void * state ) {
303
+ static inline size_t xorshift128plus_dynamic_generate_size (void * state ) {
293
304
return sizeof (uint64_t );
294
305
}
295
306
@@ -362,7 +373,7 @@ static zend_object *php_random_engine_xorshift128plus_new(zend_class_entry *ce)
362
373
363
374
/* MersenneTwister begin */
364
375
365
- static inline size_t mersennetwister_size (void * state ) {
376
+ static inline size_t mersennetwister_dynamic_generate__size (void * state ) {
366
377
return sizeof (uint32_t );
367
378
}
368
379
@@ -484,7 +495,7 @@ static zend_object *php_random_engine_mersennetwister_new(zend_class_entry *ce)
484
495
485
496
/* CombinedLCG begin */
486
497
487
- static inline size_t combinedlcg_size (void * state ) {
498
+ static inline size_t combinedlcg_dynamic_generate__size (void * state ) {
488
499
return sizeof (uint32_t );
489
500
}
490
501
@@ -581,7 +592,7 @@ static zend_object *php_random_engine_combinedlcg_new(zend_class_entry *ce) {
581
592
582
593
/* Secure begin */
583
594
584
- static inline size_t secure_size (void * state ) {
595
+ static inline size_t secure_dynamic_generate_size (void * state ) {
585
596
return sizeof (uint64_t );
586
597
}
587
598
@@ -601,13 +612,10 @@ static zend_object *php_random_engine_secure_new(zend_class_entry *ce) {
601
612
602
613
/* User begin */
603
614
604
- static inline size_t user_size (void * state ) {
615
+ static inline size_t user_dynamic_generate_size (void * state ) {
605
616
php_random_engine_state_user * s = (php_random_engine_state_user * ) state ;
606
- zval retval ;
607
617
608
- zend_call_known_instance_method_with_0_params (s -> size_method , s -> object , & retval );
609
-
610
- return (size_t ) zval_get_long (& retval );
618
+ return s -> last_generate_size ;
611
619
}
612
620
613
621
static uint64_t user_generate (void * state ) {
@@ -619,13 +627,11 @@ static uint64_t user_generate(void *state) {
619
627
620
628
zend_call_known_instance_method_with_0_params (s -> generate_method , s -> object , & retval );
621
629
622
- /* not supported over 64-bit wide currently */
623
- size = user_size (state );
624
- if (size > sizeof (uint64_t )) {
625
- size = sizeof (uint64_t );
626
- }
630
+ /* Store generated size in a state */
631
+ size = Z_STR (retval )-> len ;
632
+ s -> last_generate_size = size ;
627
633
628
- /* Endianness safe */
634
+ /* Endianness safe copy */
629
635
char * ptr = (char * ) & result ;
630
636
for (i = 0 ; i < size ; i ++ ) {
631
637
ptr [i ] = Z_STR (retval )-> val [i ];
@@ -639,44 +645,49 @@ static uint64_t user_generate(void *state) {
639
645
/* User end */
640
646
641
647
const php_random_engine_algo php_random_engine_algo_xorshift128plus = {
648
+ sizeof (uint64_t ),
649
+ xorshift128plus_dynamic_generate_size ,
642
650
sizeof (php_random_engine_state_xorshift128plus ),
643
- xorshift128plus_size ,
644
651
xorshift128plus_generate ,
645
652
xorshift128plus_seed ,
646
653
xorshift128plus_serialize ,
647
654
xorshift128plus_unserialize
648
655
};
649
656
650
657
const php_random_engine_algo php_random_engine_algo_mersennetwister = {
658
+ sizeof (uint32_t ),
659
+ mersennetwister_dynamic_generate__size ,
651
660
sizeof (php_random_engine_state_mersennetwister ),
652
- mersennetwister_size ,
653
661
mersennetwister_generate ,
654
662
mersennetwister_seed ,
655
663
mersennetwister_serialize ,
656
664
mersennetwister_unserialize
657
665
};
658
666
659
667
const php_random_engine_algo php_random_engine_algo_combinedlcg = {
668
+ sizeof (uint32_t ),
669
+ combinedlcg_dynamic_generate__size ,
660
670
sizeof (php_random_engine_state_combinedlcg ),
661
- combinedlcg_size ,
662
671
combinedlcg_generate ,
663
672
combinedlcg_seed ,
664
673
combinedlcg_serialize ,
665
674
combinedlcg_unserialize
666
675
};
667
676
668
677
const php_random_engine_algo php_random_engine_algo_secure = {
678
+ sizeof (uint64_t ),
679
+ secure_dynamic_generate_size ,
669
680
0 ,
670
- secure_size ,
671
681
secure_generate ,
672
682
NULL ,
673
683
NULL ,
674
684
NULL
675
685
};
676
686
677
687
const php_random_engine_algo php_random_engine_algo_user = {
688
+ 0 , /* does not support static generate size */
689
+ user_dynamic_generate_size , /* always use dynamic_generate_size */
678
690
sizeof (php_random_engine_state_user ),
679
- user_size ,
680
691
user_generate ,
681
692
NULL ,
682
693
NULL ,
@@ -988,7 +999,7 @@ PHPAPI zend_long php_random_engine_range(const php_random_engine_algo *algo, voi
988
999
{
989
1000
zend_ulong umax = max - min ;
990
1001
991
- if (algo -> size (state ) >= sizeof (uint64_t )) {
1002
+ if (algo -> dynamic_generate_size (state ) >= sizeof (uint64_t )) {
992
1003
return (zend_long ) rand_range64 (algo , state , umax ) + min ;
993
1004
}
994
1005
@@ -1169,7 +1180,7 @@ PHP_METHOD(Random_Engine_XorShift128Plus, __construct)
1169
1180
if (str_seed ) {
1170
1181
/* char (8 bit) * 16 = 128 bits */
1171
1182
if (str_seed -> len == 16 ) {
1172
- /* Endianness safe */
1183
+ /* Endianness safe copy */
1173
1184
int i ;
1174
1185
char * ptr = (char * ) & state -> s ;
1175
1186
for (i = 0 ; i < 16 ; i ++ ) {
@@ -1185,17 +1196,6 @@ PHP_METHOD(Random_Engine_XorShift128Plus, __construct)
1185
1196
}
1186
1197
/* }}} */
1187
1198
1188
- /* {{{ Get a generate random number byte size */
1189
- PHP_METHOD (Random_Engine_XorShift128Plus , nextByteSize )
1190
- {
1191
- php_random_engine * engine = Z_RANDOM_ENGINE_P (ZEND_THIS );
1192
-
1193
- ZEND_PARSE_PARAMETERS_NONE ();
1194
-
1195
- RETURN_LONG ((zend_long ) engine -> algo -> size (engine -> state ));
1196
- }
1197
- /* }}} */
1198
-
1199
1199
/* {{{ Generate a random number */
1200
1200
PHP_METHOD (Random_Engine_XorShift128Plus , generate )
1201
1201
{
@@ -1208,10 +1208,10 @@ PHP_METHOD(Random_Engine_XorShift128Plus, generate)
1208
1208
ZEND_PARSE_PARAMETERS_NONE ();
1209
1209
1210
1210
generated = engine -> algo -> generate (engine -> state );
1211
- size = engine -> algo -> size (engine -> state );
1211
+ size = engine -> algo -> dynamic_generate_size (engine -> state );
1212
1212
bytes = zend_string_alloc (size , 0 );
1213
1213
1214
- /* Endianness safe */
1214
+ /* Endianness safe copy */
1215
1215
for (i = 0 ; i < size ; i ++ ) {
1216
1216
bytes -> val [i ] = (generated >> (i * 8 )) & 0xff ;
1217
1217
}
@@ -1435,11 +1435,11 @@ PHP_METHOD(Random_Randomizer, getBytes)
1435
1435
ret = zend_string_alloc (length , 0 );
1436
1436
1437
1437
while (generated_bytes <= length ) {
1438
- size_t generated_size = randomizer -> algo -> size (randomizer -> state );
1438
+ size_t generated_size = randomizer -> algo -> dynamic_generate_size (randomizer -> state );
1439
1439
1440
1440
buf = randomizer -> algo -> generate (randomizer -> state );
1441
1441
while (generated_size < sizeof (uint64_t )) {
1442
- size_t generate_size = randomizer -> algo -> size (randomizer -> state );
1442
+ size_t generate_size = randomizer -> algo -> dynamic_generate_size (randomizer -> state );
1443
1443
1444
1444
buf = (buf << generate_size ) | randomizer -> algo -> generate (randomizer -> state );
1445
1445
0 commit comments