From 6f9bee9763ccf54efb859cff58889ced5c7e0058 Mon Sep 17 00:00:00 2001 From: Volodymyr Panivko Date: Sat, 7 Mar 2026 14:16:50 +0100 Subject: [PATCH 1/2] THRIFT-5587: Add UUID support for PHP Implement UUID as a first-class type in the PHP library and code generator. UUID (wire type 16, compact protocol type 0x0D) is represented as a string in canonical form (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx), consistent with the Python approach. Fixed 16 bytes on wire in binary/compact protocols, JSON string in JSON protocol. Changes: - TType: add UUID = 16 constant - TProtocol: add abstract writeUuid/readUuid, UUID cases in skip/skipBinary - TBinaryProtocol: implement writeUuid/readUuid (16 raw bytes) - TCompactProtocol: add COMPACT_UUID = 0x0D, type mappings, writeUuid/readUuid - TJSONProtocol: add NAME_UUID = "uid", type mappings, writeUuid/readUuid - TSimpleJSONProtocol: add writeUuid/readUuid - TProtocolDecorator: add writeUuid/readUuid delegation - TBase: add UUID to $tmethod dispatch array - t_php_generator.cc: add TYPE_UUID in all code generation switch statements - Update test configs to use current ThriftTest.thrift (with UUID fields) - Add UUID unit tests for TBinaryProtocol and TCompactProtocol Client: php Patch: Volodymyr Panivko --- .../src/thrift/generate/t_php_generator.cc | 27 +++++++++++++++++ lib/php/lib/Base/TBase.php | 3 +- lib/php/lib/Protocol/TBinaryProtocol.php | 21 +++++++++++++ lib/php/lib/Protocol/TCompactProtocol.php | 24 +++++++++++++++ lib/php/lib/Protocol/TJSONProtocol.php | 18 +++++++++++ lib/php/lib/Protocol/TProtocol.php | 8 +++++ lib/php/lib/Protocol/TProtocolDecorator.php | 10 +++++++ lib/php/lib/Protocol/TSimpleJSONProtocol.php | 10 +++++++ lib/php/lib/Type/TType.php | 1 + lib/php/test/Resources/ThriftTest.thrift | 2 +- .../Unit/Lib/Protocol/TBinaryProtocolTest.php | 30 +++++++++++++++++++ .../Lib/Protocol/TCompactProtocolTest.php | 30 +++++++++++++++++++ test/php/Handler.php | 5 ++++ test/php/Makefile.am | 8 ++--- test/php/TestClient.php | 15 ++++++++++ 15 files changed, 206 insertions(+), 6 deletions(-) diff --git a/compiler/cpp/src/thrift/generate/t_php_generator.cc b/compiler/cpp/src/thrift/generate/t_php_generator.cc index 6879501db0f..45ae7198676 100644 --- a/compiler/cpp/src/thrift/generate/t_php_generator.cc +++ b/compiler/cpp/src/thrift/generate/t_php_generator.cc @@ -671,6 +671,9 @@ string t_php_generator::render_const_value(t_type* type, t_const_value* value) { out << value->get_double(); } break; + case t_base_type::TYPE_UUID: + out << '"' << get_escaped_string(value) << '"'; + break; default: throw "compiler error: no const of base type " + t_base_type::t_base_name(tbase); } @@ -2175,6 +2178,15 @@ void t_php_generator::generate_deserialize_field(ostream& out, out << indent() << "$arr = unpack('d', strrev(" << itrans << "->readAll(8)));" << '\n' << indent() << "$" << name << " = $arr[1];" << '\n'; break; + case t_base_type::TYPE_UUID: + out << indent() << "$_uuid_bin = " << itrans << "->readAll(16);" << '\n' + << indent() << "$_uuid_hex = bin2hex($_uuid_bin);" << '\n' + << indent() << "$" << name << " = substr($_uuid_hex, 0, 8) . '-' . " + << "substr($_uuid_hex, 8, 4) . '-' . " + << "substr($_uuid_hex, 12, 4) . '-' . " + << "substr($_uuid_hex, 16, 4) . '-' . " + << "substr($_uuid_hex, 20, 12);" << '\n'; + break; default: throw "compiler error: no PHP name for base type " + t_base_type::t_base_name(tbase) + tfield->get_name(); @@ -2216,6 +2228,9 @@ void t_php_generator::generate_deserialize_field(ostream& out, case t_base_type::TYPE_DOUBLE: out << "readDouble($" << name << ");"; break; + case t_base_type::TYPE_UUID: + out << "readUuid($" << name << ");"; + break; default: throw "compiler error: no PHP name for base type " + t_base_type::t_base_name(tbase); } @@ -2417,6 +2432,9 @@ void t_php_generator::generate_serialize_field(ostream& out, t_field* tfield, st case t_base_type::TYPE_DOUBLE: out << indent() << "$output .= strrev(pack('d', $" << name << "));" << '\n'; break; + case t_base_type::TYPE_UUID: + out << indent() << "$output .= hex2bin(str_replace('-', '', $" << name << "));" << '\n'; + break; default: throw "compiler error: no PHP name for base type " + t_base_type::t_base_name(tbase); } @@ -2454,6 +2472,9 @@ void t_php_generator::generate_serialize_field(ostream& out, t_field* tfield, st case t_base_type::TYPE_DOUBLE: out << "writeDouble($" << name << ");"; break; + case t_base_type::TYPE_UUID: + out << "writeUuid($" << name << ");"; + break; default: throw "compiler error: no PHP name for base type " + t_base_type::t_base_name(tbase); } @@ -2782,6 +2803,8 @@ string t_php_generator::type_to_cast(t_type* type) { return "(double)"; case t_base_type::TYPE_STRING: return "(string)"; + case t_base_type::TYPE_UUID: + return "(string)"; default: return ""; } @@ -2816,6 +2839,8 @@ string t_php_generator::type_to_enum(t_type* type) { return "TType::I64"; case t_base_type::TYPE_DOUBLE: return "TType::DOUBLE"; + case t_base_type::TYPE_UUID: + return "TType::UUID"; default: throw "compiler error: unhandled type"; } @@ -2859,6 +2884,8 @@ string t_php_generator::type_to_phpdoc(t_type* type) { return "int"; case t_base_type::TYPE_DOUBLE: return "double"; + case t_base_type::TYPE_UUID: + return "string"; default: throw "compiler error: unhandled type"; } diff --git a/lib/php/lib/Base/TBase.php b/lib/php/lib/Base/TBase.php index d946665ecdc..8da03ce176e 100644 --- a/lib/php/lib/Base/TBase.php +++ b/lib/php/lib/Base/TBase.php @@ -41,7 +41,8 @@ abstract class TBase TType::I32 => 'I32', TType::I64 => 'I64', TType::DOUBLE => 'Double', - TType::STRING => 'String' + TType::STRING => 'String', + TType::UUID => 'Uuid' ); abstract public function read($input); diff --git a/lib/php/lib/Protocol/TBinaryProtocol.php b/lib/php/lib/Protocol/TBinaryProtocol.php index cda5c0d4c7a..fd51f672783 100644 --- a/lib/php/lib/Protocol/TBinaryProtocol.php +++ b/lib/php/lib/Protocol/TBinaryProtocol.php @@ -220,6 +220,14 @@ public function writeString($value) return $result + $len; } + public function writeUuid($uuid) + { + $data = hex2bin(str_replace('-', '', $uuid)); + $this->trans_->write($data, 16); + + return 16; + } + public function readMessageBegin(&$name, &$type, &$seqid) { $result = $this->readI32($sz); @@ -450,4 +458,17 @@ public function readString(&$value) return $result + $len; } + + public function readUuid(&$value) + { + $data = $this->trans_->readAll(16); + $hex = bin2hex($data); + $value = substr($hex, 0, 8) . '-' . + substr($hex, 8, 4) . '-' . + substr($hex, 12, 4) . '-' . + substr($hex, 16, 4) . '-' . + substr($hex, 20, 12); + + return 16; + } } diff --git a/lib/php/lib/Protocol/TCompactProtocol.php b/lib/php/lib/Protocol/TCompactProtocol.php index ebe32e52819..3058bbae474 100644 --- a/lib/php/lib/Protocol/TCompactProtocol.php +++ b/lib/php/lib/Protocol/TCompactProtocol.php @@ -45,6 +45,7 @@ class TCompactProtocol extends TProtocol const COMPACT_SET = 0x0A; const COMPACT_MAP = 0x0B; const COMPACT_STRUCT = 0x0C; + const COMPACT_UUID = 0x0D; const STATE_CLEAR = 0; const STATE_FIELD_WRITE = 1; @@ -76,6 +77,7 @@ class TCompactProtocol extends TProtocol TType::LST => TCompactProtocol::COMPACT_LIST, TType::SET => TCompactProtocol::COMPACT_SET, TType::MAP => TCompactProtocol::COMPACT_MAP, + TType::UUID => TCompactProtocol::COMPACT_UUID, ); protected static $ttypes = array( @@ -92,6 +94,7 @@ class TCompactProtocol extends TProtocol TCompactProtocol::COMPACT_LIST => TType::LST, TCompactProtocol::COMPACT_SET => TType::SET, TCompactProtocol::COMPACT_MAP => TType::MAP, + TCompactProtocol::COMPACT_UUID => TType::UUID, ); protected $state = TCompactProtocol::STATE_CLEAR; @@ -370,6 +373,14 @@ public function writeString($value) return $result + $len; } + public function writeUuid($uuid) + { + $data = hex2bin(str_replace('-', '', $uuid)); + $this->trans_->write($data, 16); + + return 16; + } + public function readFieldBegin(&$name, &$field_type, &$field_id) { $result = $this->readUByte($compact_type_and_delta); @@ -587,6 +598,19 @@ public function readString(&$value) return $result + $len; } + public function readUuid(&$value) + { + $data = $this->trans_->readAll(16); + $hex = bin2hex($data); + $value = substr($hex, 0, 8) . '-' . + substr($hex, 8, 4) . '-' . + substr($hex, 12, 4) . '-' . + substr($hex, 16, 4) . '-' . + substr($hex, 20, 12); + + return 16; + } + public function getTType($byte) { return self::$ttypes[$byte & 0x0f]; diff --git a/lib/php/lib/Protocol/TJSONProtocol.php b/lib/php/lib/Protocol/TJSONProtocol.php index cfd3c8b2b53..1e8c3918578 100644 --- a/lib/php/lib/Protocol/TJSONProtocol.php +++ b/lib/php/lib/Protocol/TJSONProtocol.php @@ -74,6 +74,7 @@ class TJSONProtocol extends TProtocol const NAME_MAP = "map"; const NAME_LIST = "lst"; const NAME_SET = "set"; + const NAME_UUID = "uid"; private function getTypeNameForTypeID($typeID) { @@ -100,6 +101,8 @@ private function getTypeNameForTypeID($typeID) return self::NAME_SET; case TType::LST: return self::NAME_LIST; + case TType::UUID: + return self::NAME_UUID; default: throw new TProtocolException("Unrecognized type", TProtocolException::UNKNOWN); } @@ -149,6 +152,9 @@ private function getTypeIDForTypeName($name) case 't': $result = TType::BOOL; break; + case 'u': + $result = TType::UUID; + break; } } if ($result == TType::STOP) { @@ -574,6 +580,11 @@ public function writeString($str) $this->writeJSONString($str); } + public function writeUuid($uuid) + { + $this->writeJSONString($uuid); + } + /** * Reads the message header * @@ -730,4 +741,11 @@ public function readString(&$str) return true; } + + public function readUuid(&$uuid) + { + $uuid = $this->readJSONString(false); + + return true; + } } diff --git a/lib/php/lib/Protocol/TProtocol.php b/lib/php/lib/Protocol/TProtocol.php index 0de2cf5d42a..400078a82d4 100644 --- a/lib/php/lib/Protocol/TProtocol.php +++ b/lib/php/lib/Protocol/TProtocol.php @@ -129,6 +129,8 @@ abstract public function writeDouble($dub); abstract public function writeString($str); + abstract public function writeUuid($uuid); + /** * Reads the message header * @@ -177,6 +179,8 @@ abstract public function readDouble(&$dub); abstract public function readString(&$str); + abstract public function readUuid(&$uuid); + /** * The skip function is a utility to parse over unrecognized date without * causing corruption. @@ -200,6 +204,8 @@ public function skip($type) return $this->readDouble($dub); case TType::STRING: return $this->readString($str); + case TType::UUID: + return $this->readUuid($uuid); case TType::STRUCT: $result = $this->readStructBegin($name); while (true) { @@ -271,6 +277,8 @@ public static function skipBinary($itrans, $type) return $itrans->readAll(8); case TType::DOUBLE: return $itrans->readAll(8); + case TType::UUID: + return $itrans->readAll(16); case TType::STRING: $len = unpack('N', $itrans->readAll(4)); $len = $len[1]; diff --git a/lib/php/lib/Protocol/TProtocolDecorator.php b/lib/php/lib/Protocol/TProtocolDecorator.php index a85e0b8e54c..60732fc49de 100644 --- a/lib/php/lib/Protocol/TProtocolDecorator.php +++ b/lib/php/lib/Protocol/TProtocolDecorator.php @@ -178,6 +178,11 @@ public function writeString($str) return $this->concreteProtocol_->writeString($str); } + public function writeUuid($uuid) + { + return $this->concreteProtocol_->writeUuid($uuid); + } + /** * Reads the message header * @@ -282,4 +287,9 @@ public function readString(&$str) { return $this->concreteProtocol_->readString($str); } + + public function readUuid(&$uuid) + { + return $this->concreteProtocol_->readUuid($uuid); + } } diff --git a/lib/php/lib/Protocol/TSimpleJSONProtocol.php b/lib/php/lib/Protocol/TSimpleJSONProtocol.php index 22f17423bc4..982bfd3e6c4 100644 --- a/lib/php/lib/Protocol/TSimpleJSONProtocol.php +++ b/lib/php/lib/Protocol/TSimpleJSONProtocol.php @@ -270,6 +270,11 @@ public function writeString($str) $this->writeJSONString($str); } + public function writeUuid($uuid) + { + $this->writeJSONString($uuid); + } + /** * Reading methods. * @@ -372,4 +377,9 @@ public function readString(&$str) { throw new TException("Not implemented"); } + + public function readUuid(&$uuid) + { + throw new TException("Not implemented"); + } } diff --git a/lib/php/lib/Type/TType.php b/lib/php/lib/Type/TType.php index 3fdb15f536e..fd10cfd6189 100644 --- a/lib/php/lib/Type/TType.php +++ b/lib/php/lib/Type/TType.php @@ -42,6 +42,7 @@ class TType const MAP = 13; const SET = 14; const LST = 15; // N.B. cannot use LIST keyword in PHP! + const UUID = 16; const UTF8 = 16; const UTF16 = 17; } diff --git a/lib/php/test/Resources/ThriftTest.thrift b/lib/php/test/Resources/ThriftTest.thrift index 07ca6e49203..97b4834ac28 100644 --- a/lib/php/test/Resources/ThriftTest.thrift +++ b/lib/php/test/Resources/ThriftTest.thrift @@ -19,7 +19,7 @@ namespace php TestValidators -include "../../../../test/v0.16/ThriftTest.thrift" +include "../../../../test/ThriftTest.thrift" union UnionOfStrings { 1: string aa; diff --git a/lib/php/test/Unit/Lib/Protocol/TBinaryProtocolTest.php b/lib/php/test/Unit/Lib/Protocol/TBinaryProtocolTest.php index 2648b556315..c89555cee57 100644 --- a/lib/php/test/Unit/Lib/Protocol/TBinaryProtocolTest.php +++ b/lib/php/test/Unit/Lib/Protocol/TBinaryProtocolTest.php @@ -413,6 +413,36 @@ public function testWriteString() $this->assertEquals(10, $protocol->writeString($value)); } + public function testWriteUuid() + { + $uuid = '01234567-89ab-cdef-0123-456789abcdef'; + $transport = $this->createMock(TTransport::class); + $protocol = new TBinaryProtocol($transport, false, false); + + $transport + ->expects($this->once()) + ->method('write') + ->with(hex2bin('0123456789abcdef0123456789abcdef'), 16) + ->willReturn(16); + + $this->assertEquals(16, $protocol->writeUuid($uuid)); + } + + public function testReadUuid() + { + $transport = $this->createMock(TTransport::class); + $protocol = new TBinaryProtocol($transport, false, false); + + $transport + ->expects($this->once()) + ->method('readAll') + ->with(16) + ->willReturn(hex2bin('0123456789abcdef0123456789abcdef')); + + $this->assertEquals(16, $protocol->readUuid($value)); + $this->assertEquals('01234567-89ab-cdef-0123-456789abcdef', $value); + } + /** * @dataProvider readMessageBeginDataProvider */ diff --git a/lib/php/test/Unit/Lib/Protocol/TCompactProtocolTest.php b/lib/php/test/Unit/Lib/Protocol/TCompactProtocolTest.php index 95f972cf268..2474ec09a64 100644 --- a/lib/php/test/Unit/Lib/Protocol/TCompactProtocolTest.php +++ b/lib/php/test/Unit/Lib/Protocol/TCompactProtocolTest.php @@ -794,6 +794,36 @@ public function testWriteString() $this->assertSame(5, $protocol->writeString('test')); } + public function testWriteUuid() + { + $uuid = '01234567-89ab-cdef-0123-456789abcdef'; + $transport = $this->createMock(TTransport::class); + $protocol = new TCompactProtocol($transport); + + $transport + ->expects($this->once()) + ->method('write') + ->with(hex2bin('0123456789abcdef0123456789abcdef'), 16) + ->willReturn(16); + + $this->assertSame(16, $protocol->writeUuid($uuid)); + } + + public function testReadUuid() + { + $transport = $this->createMock(TTransport::class); + $protocol = new TCompactProtocol($transport); + + $transport + ->expects($this->once()) + ->method('readAll') + ->with(16) + ->willReturn(hex2bin('0123456789abcdef0123456789abcdef')); + + $this->assertSame(16, $protocol->readUuid($value)); + $this->assertSame('01234567-89ab-cdef-0123-456789abcdef', $value); + } + /** * @dataProvider writeI64DataProvider */ diff --git a/test/php/Handler.php b/test/php/Handler.php index 5ca06a21d03..3ea1f584f6b 100644 --- a/test/php/Handler.php +++ b/test/php/Handler.php @@ -42,6 +42,11 @@ public function testBinary($thing) return $thing; } + public function testUuid($thing) + { + return $thing; + } + public function testStruct(\ThriftTest\Xtruct $thing) { return $thing; diff --git a/test/php/Makefile.am b/test/php/Makefile.am index 1cffdd4f503..60a63cf5d78 100644 --- a/test/php/Makefile.am +++ b/test/php/Makefile.am @@ -17,11 +17,11 @@ # under the License. # -stubs: ../v0.16/ThriftTest.thrift - $(THRIFT) --gen php ../v0.16/ThriftTest.thrift - $(THRIFT) --gen php:inlined ../v0.16/ThriftTest.thrift +stubs: ../ThriftTest.thrift + $(THRIFT) --gen php ../ThriftTest.thrift + $(THRIFT) --gen php:inlined ../ThriftTest.thrift $(MKDIR_P) gen-php-classmap - $(THRIFT) -out gen-php-classmap --gen php:classmap ../v0.16/ThriftTest.thrift + $(THRIFT) -out gen-php-classmap --gen php:classmap ../ThriftTest.thrift php_ext_dir: mkdir -p php_ext_dir diff --git a/test/php/TestClient.php b/test/php/TestClient.php index acd901d883b..fba0178ba27 100755 --- a/test/php/TestClient.php +++ b/test/php/TestClient.php @@ -188,6 +188,21 @@ function roundtrip($testClient, $method, $value) { * BINARY TEST -- TODO */ +/** + * UUID TEST + */ +print_r("testUuid('00000000-0000-0000-0000-000000000000')"); +$uuid_in = '00000000-0000-0000-0000-000000000000'; +$uuid_out = $testClient->testUuid($uuid_in); +print_r(" = \"$uuid_out\"\n"); +if ($uuid_in !== $uuid_out) { + echo "**FAILED**\n"; + $exitcode |= ERR_BASETYPES; +} + +roundtrip($testClient, 'testUuid', '00000000-0000-0000-0000-000000000000'); +roundtrip($testClient, 'testUuid', '550e8400-e29b-41d4-a716-446655440000'); + /** * STRUCT TEST */ From 118b7b10f0500806c596d3847c2ea3a25c06d7a9 Mon Sep 17 00:00:00 2001 From: Volodymyr Panivko Date: Mon, 9 Mar 2026 08:15:35 +0100 Subject: [PATCH 2/2] THRIFT-5587: Add UUID validation for PHP Validate UUID format on write (all protocols) and on read (JSON protocol) using the canonical regex pattern. Throws TProtocolException on invalid input. --- lib/php/lib/Protocol/TBinaryProtocol.php | 1 + lib/php/lib/Protocol/TCompactProtocol.php | 1 + lib/php/lib/Protocol/TJSONProtocol.php | 2 ++ lib/php/lib/Protocol/TProtocol.php | 7 ++++++ .../Unit/Lib/Protocol/TBinaryProtocolTest.php | 24 +++++++++++++++++++ .../Lib/Protocol/TCompactProtocolTest.php | 24 +++++++++++++++++++ 6 files changed, 59 insertions(+) diff --git a/lib/php/lib/Protocol/TBinaryProtocol.php b/lib/php/lib/Protocol/TBinaryProtocol.php index fd51f672783..bb079b6aeb9 100644 --- a/lib/php/lib/Protocol/TBinaryProtocol.php +++ b/lib/php/lib/Protocol/TBinaryProtocol.php @@ -222,6 +222,7 @@ public function writeString($value) public function writeUuid($uuid) { + self::validateUuid($uuid); $data = hex2bin(str_replace('-', '', $uuid)); $this->trans_->write($data, 16); diff --git a/lib/php/lib/Protocol/TCompactProtocol.php b/lib/php/lib/Protocol/TCompactProtocol.php index 3058bbae474..19e4d1754fe 100644 --- a/lib/php/lib/Protocol/TCompactProtocol.php +++ b/lib/php/lib/Protocol/TCompactProtocol.php @@ -375,6 +375,7 @@ public function writeString($value) public function writeUuid($uuid) { + self::validateUuid($uuid); $data = hex2bin(str_replace('-', '', $uuid)); $this->trans_->write($data, 16); diff --git a/lib/php/lib/Protocol/TJSONProtocol.php b/lib/php/lib/Protocol/TJSONProtocol.php index 1e8c3918578..62b2f508819 100644 --- a/lib/php/lib/Protocol/TJSONProtocol.php +++ b/lib/php/lib/Protocol/TJSONProtocol.php @@ -582,6 +582,7 @@ public function writeString($str) public function writeUuid($uuid) { + self::validateUuid($uuid); $this->writeJSONString($uuid); } @@ -745,6 +746,7 @@ public function readString(&$str) public function readUuid(&$uuid) { $uuid = $this->readJSONString(false); + self::validateUuid($uuid); return true; } diff --git a/lib/php/lib/Protocol/TProtocol.php b/lib/php/lib/Protocol/TProtocol.php index 400078a82d4..18fe6fcb970 100644 --- a/lib/php/lib/Protocol/TProtocol.php +++ b/lib/php/lib/Protocol/TProtocol.php @@ -131,6 +131,13 @@ abstract public function writeString($str); abstract public function writeUuid($uuid); + protected static function validateUuid($uuid) + { + if (!is_string($uuid) || !preg_match('/^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/', $uuid)) { + throw new TProtocolException('Invalid UUID format', TProtocolException::INVALID_DATA); + } + } + /** * Reads the message header * diff --git a/lib/php/test/Unit/Lib/Protocol/TBinaryProtocolTest.php b/lib/php/test/Unit/Lib/Protocol/TBinaryProtocolTest.php index c89555cee57..ab40f9989ed 100644 --- a/lib/php/test/Unit/Lib/Protocol/TBinaryProtocolTest.php +++ b/lib/php/test/Unit/Lib/Protocol/TBinaryProtocolTest.php @@ -443,6 +443,30 @@ public function testReadUuid() $this->assertEquals('01234567-89ab-cdef-0123-456789abcdef', $value); } + /** + * @dataProvider invalidUuidDataProvider + */ + public function testWriteUuidValidation($invalidUuid) + { + $transport = $this->createMock(TTransport::class); + $protocol = new TBinaryProtocol($transport, false, false); + + $this->expectException(\Thrift\Exception\TProtocolException::class); + $this->expectExceptionMessage('Invalid UUID format'); + $protocol->writeUuid($invalidUuid); + } + + public function invalidUuidDataProvider() + { + return [ + 'too short' => ['550e8400-e29b-41d4-a716'], + 'no dashes' => ['550e8400e29b41d4a716446655440000'], + 'invalid char' => ['550e8400-e29b-41d4-a716-44665544000g'], + 'empty' => [''], + 'not a string' => [12345], + ]; + } + /** * @dataProvider readMessageBeginDataProvider */ diff --git a/lib/php/test/Unit/Lib/Protocol/TCompactProtocolTest.php b/lib/php/test/Unit/Lib/Protocol/TCompactProtocolTest.php index 2474ec09a64..0c47d9b5023 100644 --- a/lib/php/test/Unit/Lib/Protocol/TCompactProtocolTest.php +++ b/lib/php/test/Unit/Lib/Protocol/TCompactProtocolTest.php @@ -824,6 +824,30 @@ public function testReadUuid() $this->assertSame('01234567-89ab-cdef-0123-456789abcdef', $value); } + /** + * @dataProvider invalidUuidDataProvider + */ + public function testWriteUuidValidation($invalidUuid) + { + $transport = $this->createMock(TTransport::class); + $protocol = new TCompactProtocol($transport); + + $this->expectException(\Thrift\Exception\TProtocolException::class); + $this->expectExceptionMessage('Invalid UUID format'); + $protocol->writeUuid($invalidUuid); + } + + public function invalidUuidDataProvider() + { + return [ + 'too short' => ['550e8400-e29b-41d4-a716'], + 'no dashes' => ['550e8400e29b41d4a716446655440000'], + 'invalid char' => ['550e8400-e29b-41d4-a716-44665544000g'], + 'empty' => [''], + 'not a string' => [12345], + ]; + } + /** * @dataProvider writeI64DataProvider */