Skip to content

Commit cc1a28a

Browse files
committed
Address review comments
1 parent 866da2f commit cc1a28a

12 files changed

Lines changed: 109 additions & 26 deletions

ext/uuid/config.m4

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ dnl
33

44
PHP_INSTALL_HEADERS([ext/uuid], m4_normalize([
55
php_uuid.h
6-
uuidv7-h/php_uuid.h
6+
uuidv7-h/uuidv7.h
77
]))
88

99
PHP_NEW_EXTENSION(uuid, [php_uuid.c], [no],,[-DZEND_ENABLE_STATIC_TSRMLS_CACHE=1])

ext/uuid/php_uuid.c

Lines changed: 49 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,24 @@ static inline php_uuid_v7_object *php_uuid_v7_object_from_obj(zend_object *objec
5050

5151
#define Z_UUID_V7_OBJECT_P(zv) php_uuid_v7_object_from_obj(Z_OBJ_P((zv)))
5252

53+
static zend_always_inline bool php_uuid_v7_is_valid(const php_uuid_v7 uuid)
54+
{
55+
return (uuid[6] & 0xf0) == 0x70 && (uuid[8] & 0xc0) == 0x80;
56+
}
57+
5358
ZEND_ATTRIBUTE_NONNULL_ARGS(1) PHPAPI zend_result php_uuid_v7_parse(const zend_string *uuid_str, php_uuid_v7 uuid)
5459
{
5560
int result = uuidv7_from_string(ZSTR_VAL(uuid_str), uuid);
61+
if (result != 0) {
62+
return FAILURE;
63+
}
5664

57-
return result == 0 ? SUCCESS : FAILURE;
65+
return php_uuid_v7_is_valid(uuid) ? SUCCESS : FAILURE;
66+
}
67+
68+
ZEND_ATTRIBUTE_NONNULL PHPAPI zend_string *php_uuid_v7_to_bytes(const uint8_t *uuid)
69+
{
70+
return zend_string_init((const char *) uuid, 16, false);
5871
}
5972

6073
ZEND_ATTRIBUTE_NONNULL PHPAPI zend_string *php_uuid_v7_to_string(const uint8_t *uuid)
@@ -90,12 +103,12 @@ PHP_METHOD(Uuid_UuidV7, parse)
90103
object_init_ex(return_value, Z_CE_P(ZEND_THIS));
91104
php_uuid_v7_object *uuid_object = Z_UUID_V7_OBJECT_P(return_value);
92105

93-
if (uuidv7_from_string(ZSTR_VAL(uuid_str), uuid_object->uuid) == FAILURE) {
94-
zend_throw_exception(NULL, "The specified UUID v7 is malformed", 0);
95-
RETURN_THROWS();
106+
if (php_uuid_v7_parse(uuid_str, uuid_object->uuid) == FAILURE) {
107+
zval_ptr_dtor(return_value);
108+
RETURN_NULL();
96109
}
97110

98-
uuid_object->is_initialized = false;
111+
uuid_object->is_initialized = true;
99112
}
100113

101114
PHP_METHOD(Uuid_UuidV7, generate)
@@ -113,7 +126,10 @@ PHP_METHOD(Uuid_UuidV7, generate)
113126

114127
uint64_t unix_time_ms;
115128
if (datetime_object == NULL) {
116-
unix_time_ms = zend_time_mono_fallback_nsec() / 1000000;
129+
struct timespec ts;
130+
zend_time_real_spec(&ts);
131+
132+
unix_time_ms = ts.tv_sec * 1000 + ts.tv_nsec / 1000000;
117133
} else {
118134
php_date_obj *datetime = php_date_obj_from_obj(datetime_object);
119135
if (!datetime->time) {
@@ -132,17 +148,17 @@ PHP_METHOD(Uuid_UuidV7, generate)
132148
unix_time_ms = (uint64_t) Z_LVAL(zv_timestamp) * 1000;
133149
}
134150

135-
php_random_algo_with_state random_algo;
151+
php_random_algo_with_state random_engine;
136152
if (random_engine_object == NULL) {
137-
random_algo = php_random_default_engine();
153+
random_engine.algo = &php_random_algo_secure;
154+
random_engine.state = NULL;
138155
} else {
139-
php_random_engine *random_engine = php_random_engine_from_obj(random_engine_object);
140-
random_algo = random_engine->engine;
156+
random_engine = php_random_engine_from_obj(random_engine_object)->engine;
141157
}
142158

143159
uint8_t random_bytes[10];
144160
for (int i = 0; i < 10; i++) {
145-
random_bytes[i] = php_random_range(random_algo, 0, 127);
161+
random_bytes[i] = php_random_range(random_engine, 0, 255);
146162
}
147163

148164
int8_t result = uuidv7_generate(uuid_object->uuid, unix_time_ms, random_bytes, NULL);
@@ -156,11 +172,13 @@ PHP_METHOD(Uuid_UuidV7, generate)
156172
case UUIDV7_STATUS_TIMESTAMP_INC:
157173
ZEND_FALLTHROUGH;
158174
case UUIDV7_STATUS_CLOCK_ROLLBACK:
159-
ZEND_FALLTHROUGH;
175+
break;
160176
case UUIDV7_STATUS_ERR_TIMESTAMP:
161-
ZEND_FALLTHROUGH;
177+
zend_throw_error(NULL, "The generated UUID v7 timestamp is out of range");
178+
RETURN_THROWS();
162179
case UUIDV7_STATUS_ERR_TIMESTAMP_OVERFLOW:
163-
break;
180+
zend_throw_error(NULL, "The generated UUID v7 timestamp overflowed");
181+
RETURN_THROWS();
164182
default: ZEND_UNREACHABLE();
165183
}
166184

@@ -169,9 +187,20 @@ PHP_METHOD(Uuid_UuidV7, generate)
169187

170188
PHP_METHOD(Uuid_UuidV7, __construct)
171189
{
172-
ZEND_PARSE_PARAMETERS_NONE();
190+
zend_string *uuid_str;
191+
192+
ZEND_PARSE_PARAMETERS_START(1, 1)
193+
Z_PARAM_STR(uuid_str)
194+
ZEND_PARSE_PARAMETERS_END();
195+
196+
php_uuid_v7_object *uuid_object = Z_UUID_V7_OBJECT_P(ZEND_THIS);
173197

174-
zend_throw_error(NULL, "Cannot directly construct %s, use the static factory methods instead", ZSTR_VAL(Z_OBJCE_P(ZEND_THIS)->name));
198+
if (php_uuid_v7_parse(uuid_str, uuid_object->uuid) == FAILURE) {
199+
zend_throw_exception(NULL, "The specified UUID v7 is malformed", 0);
200+
RETURN_THROWS();
201+
}
202+
203+
uuid_object->is_initialized = true;
175204
}
176205

177206
PHP_METHOD(Uuid_UuidV7, equals)
@@ -209,7 +238,7 @@ PHP_METHOD(Uuid_UuidV7, toBytes)
209238

210239
php_uuid_v7_object *uuid_object = Z_UUID_V7_OBJECT_P(ZEND_THIS);
211240

212-
RETURN_STR(php_uuid_v7_to_string(uuid_object->uuid));
241+
RETURN_STR(php_uuid_v7_to_bytes(uuid_object->uuid));
213242
}
214243

215244
PHP_METHOD(Uuid_UuidV7, toString)
@@ -302,6 +331,8 @@ PHP_METHOD(Uuid_UuidV7, __unserialize)
302331
zend_throw_exception_ex(NULL, 0, "Invalid serialization data for %s object", ZSTR_VAL(uuid_object->std.ce->name));
303332
RETURN_THROWS();
304333
}
334+
335+
uuid_object->is_initialized = true;
305336
}
306337

307338
PHP_METHOD(Uuid_UuidV7, __debugInfo)
@@ -343,6 +374,7 @@ ZEND_ATTRIBUTE_NONNULL zend_object *php_uuid_v7_object_handler_clone(zend_object
343374
php_uuid_v7_object *new_uuid_object = php_uuid_v7_object_from_obj(object->ce->create_object(object->ce));
344375

345376
memcpy(new_uuid_object->uuid, uuid_object->uuid, sizeof(php_uuid_v7));
377+
new_uuid_object->is_initialized = true;
346378
zend_objects_clone_members(&new_uuid_object->std, &uuid_object->std);
347379

348380
return &new_uuid_object->std;

ext/uuid/php_uuid.stub.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@
55
namespace Uuid {
66
final readonly class UuidV7
77
{
8-
public static function parse(string $uuid): static {}
8+
public static function parse(string $uuid): ?static {}
99

1010
public static function generate(?\DateTimeImmutable $datetime = null, ?\Random\Engine $randomEngine = null): static {}
1111

12-
private function __construct() {}
12+
public function __construct(string $uuid) {}
1313

1414
public function toBytes(): string {}
1515

ext/uuid/php_uuid_arginfo.h

Lines changed: 5 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
--TEST--
2+
Instantiate UuidV7 with its constructor
3+
--FILE--
4+
<?php
5+
6+
$uuid = new Uuid\UuidV7("00000bff-896a-782f-a96a-1b5f4f502630");
7+
8+
var_dump($uuid);
9+
?>
10+
--EXPECTF--
11+
object(Uuid\UuidV7)#%d (%d) {
12+
["uuid"]=>
13+
string(36) "00000bff-896a-782f-a96a-1b5f4f502630"
14+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
--TEST--
2+
Instantiate UuidV7 from an UUID v4 string
3+
--FILE--
4+
<?php
5+
6+
try {
7+
new Uuid\UuidV7("d70f042a-c5ca-4726-b259-795e47fd1b95");
8+
} catch (Throwable $e) {
9+
echo $e::class, ": ", $e->getMessage(), PHP_EOL;
10+
}
11+
12+
?>
13+
--EXPECT--
14+
Exception: The specified UUID v7 is malformed
File renamed without changes.

ext/uuid/tests/v7_generate_basic.phpt renamed to ext/uuid/tests/v7_generate_seed_success.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,5 @@ var_dump($uuid);
1414
--EXPECTF--
1515
object(Uuid\UuidV7)#%s (%s) {
1616
["uuid"]=>
17-
string(36) "019b76da-a800-7819-8e76-39652553744d"
17+
string(36) "019b76da-a800-7899-8ef6-b965a5d3744d"
1818
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
--TEST--
2+
Parse UUID v4 string
3+
--FILE--
4+
<?php
5+
6+
var_dump(Uuid\UuidV7::parse("d70f042a-c5ca-4726-b259-795e47fd1b95"));
7+
8+
?>
9+
--EXPECT--
10+
NULL

0 commit comments

Comments
 (0)