Coverage Report

Created: 2026-06-02 06:39

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/php-src/ext/random/engine_user.c
Line
Count
Source
1
/*
2
   +----------------------------------------------------------------------+
3
   | Copyright © The PHP Group and Contributors.                          |
4
   +----------------------------------------------------------------------+
5
   | This source file is subject to the Modified BSD License that is      |
6
   | bundled with this package in the file LICENSE, and is available      |
7
   | through the World Wide Web at <https://www.php.net/license/>.        |
8
   |                                                                      |
9
   | SPDX-License-Identifier: BSD-3-Clause                                |
10
   +----------------------------------------------------------------------+
11
   | Author: Go Kudo <zeriyoshi@php.net>                                  |
12
   +----------------------------------------------------------------------+
13
*/
14
15
#ifdef HAVE_CONFIG_H
16
# include "config.h"
17
#endif
18
19
#include "php.h"
20
#include "php_random.h"
21
22
static php_random_result generate(void *state)
23
0
{
24
0
  php_random_status_state_user *s = state;
25
0
  uint64_t result = 0;
26
0
  size_t size;
27
0
  zval retval;
28
0
  zend_string *zstr;
29
30
0
  zend_call_known_instance_method_with_0_params(s->generate_method, s->object, &retval);
31
32
0
  if (EG(exception)) {
33
0
    return (php_random_result){
34
0
      .size = sizeof(uint64_t),
35
0
      .result = 0,
36
0
    };
37
0
  }
38
39
0
  if (UNEXPECTED(Z_ISREF(retval))) {
40
0
    zstr = Z_STR_P(Z_REFVAL(retval));
41
0
  } else {
42
0
    zstr = Z_STR(retval);
43
0
  }
44
45
  /* Store generated size in a state */
46
0
  size = ZSTR_LEN(zstr);
47
48
  /* Guard for over 64-bit results */
49
0
  if (size > sizeof(uint64_t)) {
50
0
    size = sizeof(uint64_t);
51
0
  }
52
53
0
  if (size > 0) {
54
    /* Endianness safe copy */
55
0
    for (size_t i = 0; i < size; i++) {
56
0
      result += ((uint64_t) (unsigned char) ZSTR_VAL(zstr)[i]) << (8 * i);
57
0
    }
58
0
  } else {
59
0
    zend_throw_error(random_ce_Random_BrokenRandomEngineError, "A random engine must return a non-empty string");
60
0
    zval_ptr_dtor(&retval);
61
0
    return (php_random_result){
62
0
      .size = sizeof(uint64_t),
63
0
      .result = 0,
64
0
    };
65
0
  }
66
67
0
  zval_ptr_dtor(&retval);
68
69
0
  return (php_random_result){
70
0
    .size = size,
71
0
    .result = result,
72
0
  };
73
0
}
74
75
static zend_long range(void *state, zend_long min, zend_long max)
76
0
{
77
0
  return php_random_range((php_random_algo_with_state){
78
0
    .algo = &php_random_algo_user,
79
0
    .state = state,
80
0
  }, min, max);
81
0
}
82
83
PHPAPI const php_random_algo php_random_algo_user = {
84
  sizeof(php_random_status_state_user),
85
  generate,
86
  range,
87
  NULL,
88
  NULL,
89
};