@@ -388,7 +388,6 @@ PHP_METHOD(Random_Randomizer, getBytesFromString)
388
388
389
389
zend_long user_length ;
390
390
zend_string * source , * retval ;
391
- size_t total_size = 0 ;
392
391
393
392
ZEND_PARSE_PARAMETERS_START (2 , 2 );
394
393
Z_PARAM_STR (source )
@@ -410,17 +409,21 @@ PHP_METHOD(Random_Randomizer, getBytesFromString)
410
409
411
410
size_t length = (size_t )user_length ;
412
411
retval = zend_string_alloc (length , 0 );
412
+ char * rptr = ZSTR_VAL (retval );
413
+ char * sptr = ZSTR_VAL (source );
413
414
415
+ size_t to_read = length ;
414
416
if (max_offset > 0xff ) {
415
- while (total_size < length ) {
417
+ while (to_read > 0 ) {
416
418
uint64_t offset = engine .algo -> range (engine .state , 0 , max_offset );
417
419
418
420
if (EG (exception )) {
419
421
zend_string_free (retval );
420
422
RETURN_THROWS ();
421
423
}
422
424
423
- ZSTR_VAL (retval )[total_size ++ ] = ZSTR_VAL (source )[offset ];
425
+ * rptr ++ = sptr [offset ];
426
+ to_read -- ;
424
427
}
425
428
} else {
426
429
uint64_t mask = max_offset ;
@@ -432,31 +435,38 @@ PHP_METHOD(Random_Randomizer, getBytesFromString)
432
435
mask |= mask >> 2 ;
433
436
mask |= mask >> 4 ;
434
437
438
+ /* Example: if mask is 0xAB, will be 0xABABABABABABABAB */
439
+ uint64_t mask_repeat = (~((uint64_t ) 0 ) / 0xFF ) * mask ;
435
440
int failures = 0 ;
436
- while (total_size < length ) {
441
+ while (to_read > 0 ) {
437
442
php_random_result result = engine .algo -> generate (engine .state );
438
443
if (EG (exception )) {
439
444
zend_string_free (retval );
440
445
RETURN_THROWS ();
441
446
}
442
447
443
- for (size_t i = 0 ; i < result .size ; i ++ ) {
444
- uint64_t offset = (result .result >> (i * 8 )) & mask ;
445
-
448
+ uint64_t offsets = result .result & mask_repeat ;
449
+ size_t ret_size = result .size ;
450
+ while (ret_size > 0 ) {
451
+ ret_size -- ;
452
+ uint64_t offset = offsets & 0xff ;
453
+ offsets >>= 8 ;
446
454
if (offset > max_offset ) {
447
- if (++ failures > PHP_RANDOM_RANGE_ATTEMPTS ) {
455
+ if (failures == PHP_RANDOM_RANGE_ATTEMPTS ) {
448
456
zend_string_free (retval );
449
457
zend_throw_error (random_ce_Random_BrokenRandomEngineError , "Failed to generate an acceptable random number in %d attempts" , PHP_RANDOM_RANGE_ATTEMPTS );
450
458
RETURN_THROWS ();
459
+ } else {
460
+ failures ++ ;
461
+ continue ;
451
462
}
452
-
453
- continue ;
454
463
}
455
464
456
465
failures = 0 ;
457
466
458
- ZSTR_VAL (retval )[total_size ++ ] = ZSTR_VAL (source )[offset ];
459
- if (total_size >= length ) {
467
+ * rptr ++ = sptr [offset ];
468
+ to_read -- ;
469
+ if (to_read == 0 ) {
460
470
break ;
461
471
}
462
472
}
0 commit comments