diff --git a/ext/random/randomizer.c b/ext/random/randomizer.c index 76ff5bf590a88..d732628a98d2d 100644 --- a/ext/random/randomizer.c +++ b/ext/random/randomizer.c @@ -26,6 +26,7 @@ #include "Zend/zend_enum.h" #include "Zend/zend_exceptions.h" +#include "zend_portability.h" static inline void randomizer_common_init(php_random_randomizer *randomizer, zend_object *engine_object) { if (engine_object->ce->type == ZEND_INTERNAL_CLASS) { @@ -278,7 +279,6 @@ PHP_METHOD(Random_Randomizer, getBytes) zend_string *retval; zend_long user_length; - size_t total_size = 0; ZEND_PARSE_PARAMETERS_START(1, 1) Z_PARAM_LONG(user_length) @@ -291,22 +291,36 @@ PHP_METHOD(Random_Randomizer, getBytes) size_t length = (size_t)user_length; retval = zend_string_alloc(length, 0); + char *rptr = ZSTR_VAL(retval); - while (total_size < length) { + size_t to_read = length; + while (to_read > 0) { php_random_result result = engine.algo->generate(engine.state); if (EG(exception)) { zend_string_free(retval); RETURN_THROWS(); } - for (size_t i = 0; i < result.size; i++) { - ZSTR_VAL(retval)[total_size++] = (result.result >> (i * 8)) & 0xff; - if (total_size >= length) { - break; + uint64_t tmp_ret = result.result; + if (to_read >= sizeof(uint64_t) && result.size == sizeof(uint64_t)) { +#ifdef WORDS_BIGENDIAN + tmp_ret = ZEND_BYTES_SWAP64(tmp_ret); +#endif + memcpy(rptr, &tmp_ret, sizeof(uint64_t)); + to_read -= sizeof(uint64_t); + rptr += sizeof(uint64_t); + } else { + for (size_t i = 0; i < result.size; i++) { + *rptr++ = tmp_ret & 0xff; + tmp_ret >>= 8; + to_read--; + if (to_read == 0) { + break; + } } } } - ZSTR_VAL(retval)[length] = '\0'; + *rptr = '\0'; RETURN_STR(retval); } /* }}} */