THRIFT-6008: Add regression tests for recent PHP fixes#3489
Merged
Conversation
Client: php Add targeted unit tests guarding three recently-fixed bugs whose code paths had no direct test coverage: * THRIFT-6001 — TException::tmethod previously omitted TType::UUID, so UUID-typed fields in exception structs fell through to the recursive STRUCT path on write. Extend the TestRichException fixture with a uuidField (TType::UUID) and add a 'uuid' yield to TExceptionTest::writeAndReadFieldDataProvider, asserting the value round-trips intact through TBinaryProtocol. * THRIFT-5987 — TCompactProtocol::readBool in STATE_CONTAINER_READ previously passed its `?bool &$bool` reference straight into readByte(?int &$byte), leaving the caller's variable holding the raw int. Add testReadBoolInContainerState with three data-provider rows (0 → false, 1 → true, 0x7f → true) that mock TTransport, force STATE_CONTAINER_READ via reflection, and assert the value comes back as a real PHP bool. * TJSONProtocol::popContext underflow recovery — when the `$context` property was tightened to non-nullable (THRIFT-5981/5985), popContext() was patched to fall back to `new BaseContext()` instead of returning null. Add testPopContextOnEmptyStackFallsBackToBaseContext that reflects into the private method and asserts the property holds a BaseContext after popping an empty stack — no TypeError. Validation: phpcs 0 errors, phpstan level 5 0 errors, 642 unit tests (+5 new) and 108 integration tests pass. Part of umbrella THRIFT-5960 (PHP modernization). Generated-by: Claude Opus 4.7
erka
added a commit
to erka/thrift
that referenced
this pull request
May 23, 2026
* THRIFT-5978: Apply declare(strict_types=1) in PHP runtime library (#3457)
Client: php
Add declare(strict_types=1); to every PHP file in lib/php/lib/ and
non-fixture lib/php/test/, between the license docblock and the namespace.
Strict mode now enforces the native parameter and property types added in
THRIFT-5976 / THRIFT-5977 — silent scalar coercion ("5" -> 5, 0.5 -> 0)
becomes a TypeError at the call site instead of slipping through.
Coercion bugs surfaced and fixed:
* TPhpStream::__construct cast bitwise int-result of $mode & MODE_R/MODE_W
into typed bool $read/$write properties; now explicit (bool) cast and
int $mode parameter.
* TJSONProtocol::writeJSONInteger / TSimpleJSONProtocol::writeJSONInteger
wrote the int straight into the transport (which calls strlen()); now
cast to (string) before writing and the parameter is typed int.
* TJSONProtocol::writeJSONString manually wraps numeric values in QUOTE
for escapeNum contexts but then ran them through json_encode, which
added its own quotes for numeric-string inputs ("0" -> ""0"" instead
of "0"). Replaced the wrap+json_encode path with a direct numeric
emission so int and numeric-string keys round-trip identically.
* writeString is now typed string across the protocol hierarchy
(TProtocol abstract + TBinaryProtocol, TCompactProtocol, TJSONProtocol,
TSimpleJSONProtocol concrete + TProtocolDecorator). PHP map keys that
are numeric strings collapse to int internally; loose-mode generated
callers now coerce them at the call boundary instead of fataling on
strlen() inside the strict callee.
* TSocketPool::addServer is typed (string $host, int $port); the
constructor now delegates to it for the array-builder loop, so storage
shape and validation live in one place. test/php/TestClient.php and
test/php/TestServer.php parse --port=NNNN via substr() / getopt, which
return string; cast to int at the parse site so loose callers reach
the typed constructor with the right type.
* THttpClientTest::flushDataProvider declared 'port' => '80' (string);
THttpClient's promoted $port is int -- replaced with literal 80.
Generated fixtures under lib/php/test/Resources/packages/ stay untyped
(generator regen tracked separately).
Generated-by: Claude Opus 4.7
* THRIFT-5979: Add native method types to PHP Server and Factory classes (#3459)
Client: php
Migrate the public methods on lib/php/lib/Server/ and lib/php/lib/Factory/
from PHPDoc @param/@return annotations to native parameter and return
types. The Server abstractions and the protocol/transport factories are
isolated subtrees -- they reference TTransport/TProtocol only via
composition, so adding native types here does not cascade out to the
Transport or Protocol hierarchies (separate sub-tickets).
Server:
* TServer::serve() / stop() typed void.
* TSimpleServer / TForkingServer match the new abstract signatures and
drop the now-dead `if ($transport != null)` guards after accept(),
which is non-nullable.
* TForkingServer's protected helpers (handleParent, handleChild,
collectChildren) typed.
* TServerTransport::listen() / close() / acceptImpl() / accept() typed;
accept() now returns TTransport (was already that semantically -- it
throws on null), acceptImpl() returns ?TTransport, the null check
switched to strict ===.
* TServerSocket overrides typed; acceptImpl() returns ?TSocket.
* TSSLServerSocket::listen() typed; acceptImpl() returns ?TSSLSocket.
Factory:
* TProtocolFactory interface typed: getProtocol(TTransport): TProtocol.
* TBinaryProtocolFactory / TCompactProtocolFactory / TJSONProtocolFactory
match with covariant concrete return types.
* TTransportFactoryInterface typed: getTransport(TTransport): TTransport.
* TTransportFactory / TFramedTransportFactory match with covariant
return types where appropriate.
* New TBinaryProtocolAcceleratedFactory closes the long-standing gap
where TBinaryProtocolAccelerated had no library-provided factory --
the cross-test harness had to hand-roll one in test/php/TestServer.php.
The ad-hoc class is dropped in favor of the library one. The new
factory defaults strictWrite=true to match the protocol's own ctor
default, distinguishing it from TBinaryProtocolFactory.
Test fixtures (latent issues surfaced by typed signatures):
* ServerStub::serve/stop now typed void.
* ServerTransportStub uses constructor property promotion with
?TTransport and matches abstract acceptImpl(): ?TTransport.
* TSimpleServerTest had stubs of the wrong class for the factories
(TServerTransport where TTransport/TProtocol was expected); fixed.
* TForkingServerTest mocks had accept() returning null to simulate
"no connection", which violated the now-typed TTransport return.
Replaced with throwing TTransportException, which is what real
accept() does on null and what the serve() loop already catches.
* TBinaryProtocolAcceleratedFactoryTest covers the new factory.
Generated-by: Claude Opus 4.7
* THRIFT-5980: Add native method types to PHP Transport hierarchy (#3460)
Client: php
Migrate the public methods on lib/php/lib/Transport/ from PHPDoc
@param/@return annotations to native parameter and return types. This
completes the typing trajectory for the Transport subtree started by
THRIFT-5976 (properties), THRIFT-5977 (ctor promotion), THRIFT-5978
(strict_types) and THRIFT-5979 (Server + Factory method types).
Library:
* TTransport abstract: isOpen(): bool, open(): void, close(): void,
read(int): string, readAll(int): string, write(string): void,
flush(): void.
* TSocket / TSSLSocket / TSocketPool: open/close/read/write/flush typed;
setSendTimeout/setRecvTimeout/setDebug/setNumRetries/etc typed; getHost
/getPort typed; setHandle typed return.
* TBufferedTransport / TFramedTransport / TMemoryBuffer / TNullTransport
/ TPhpStream: all method overrides typed to match the abstract.
* TFramedTransport::write keeps the legacy `?int $len = null` optional
parameter so existing internal callers in TBinaryProtocol /
TCompactProtocol still type-check; the non-write path now delegates
with just the buffer.
* TCurlClient / THttpClient: read/write/flush/close/open typed; timeout
setters typed as ?float (int widens automatically); addHeaders typed
array.
Full NaN / +Infinity / -Infinity round-trip for the JSON protocols:
* TJSONProtocol now writes all three IEEE-754 sentinels as the
conventional quoted tokens ("NaN", "Infinity", "-Infinity") matching
the Java and C++ TJSONProtocol implementations; the read side gains
a "-Infinity" branch so the round-trip is symmetric. Token literals
are hoisted to TOKEN_NAN / TOKEN_POS_INFINITY / TOKEN_NEG_INFINITY
consts on TJSONProtocol following the existing NAME_* convention,
so writer and reader can never drift.
* TSimpleJSONProtocol reuses TJSONProtocol's token constants and emits
the same three tokens for its write-only path.
* The previously corrupted `{"dbl":}` / `{"thing":}` output for non-
finite doubles (locked into integration tests with #TODO markers) is
fixed; integration tests now assert the correct round-trippable
strings, plus a -Infinity case is added on both read and write paths.
Side fixes surfaced by typed transports:
* TSocket::setSendTimeout/setRecvTimeout switched to intdiv() so the
typed int property assignment is exact (floor returns float).
* TCurlClient::$timeout / $connectionTimeout and THttpClient::$timeout
tightened from float|int|null to ?float (int widens automatically).
* TBufferedTransport / TFramedTransport: stale "wBuf_" comments
referring to the old C++-style property name dropped.
Tests:
* TBinaryProtocolTest / TCompactProtocolTest / TBufferedTransportTest
/ TFramedTransportTest: dropped `->willReturn(N)` from mocks of the
now-void write/open/close/flush. Behavior unchanged; PHPUnit refuses
to mock returning a value for void methods.
* TFramedTransportTest::testWrite mock with('12345', 5) updated to
with('12345') after the non-write path now passes only the buffer.
* TCurlClientTest timeout data provider switched to float literals
(10.0 instead of 10) to match the now-typed ?float properties.
* TJSONProtocolTest gains round-trip cases for NaN, +Infinity, and
-Infinity through writeAndReadScalarDataProvider.
Generated-by: Claude Opus 4.7
* Prevent concurrent calls to socketConn.Close() in Go
Client: go
Multiple goroutines calling Close() simultaneously could result in
sc.closed.Store() being called concurrently. Use CompareAndSwap instead
to atomically check and set the closed flag, ensuring only the first
caller closes the underlying net.Conn
* Migration *.sln to *.slnx (except c++ libs)
* THRIFT-5981: Add native method types to PHP Protocol hierarchy (#3462)
Client: php
Complete the typing trajectory started by THRIFT-5976/5977/5978/5979/5980
by migrating the public methods on lib/php/lib/Protocol/ from PHPDoc-only
annotations to native PHP parameter and return types. This closes the
last of the three core hierarchies (Transport done in 5980, Server/
Factory in 5979, Protocol now).
Library:
* TProtocol abstract: all write*: int methods typed with scalar params;
all read* typed with nullable by-ref params (e.g. readMessageBegin(
?string &$name, ?int &$type, ?int &$seqid): int). skip(int $type): int
and static skipBinary(TTransport $itrans, int $type): int typed.
* TBinaryProtocol / TBinaryProtocolAccelerated / TCompactProtocol /
TJSONProtocol / TSimpleJSONProtocol / TMultiplexedProtocol /
TProtocolDecorator: all overrides typed to match the abstract.
* TJSONProtocol / TSimpleJSONProtocol write methods now return 0
explicitly (previously returned null implicitly) and the read methods
in TJSONProtocol return 1 to match the previous bool-as-int casting
behavior in generated callers that accumulate the result. A docblock
on writeMessageBegin documents the convention.
* TCompactProtocol: $boolFid and $lastFid switched from ?int to int
(defaults 0) so the typed writeFieldHeader call chain works without
explicit null-handling. $this->trans->write(...) calls drop the
vestigial second-arg byte-count (TTransport::write is single-arg
since THRIFT-5980). Concrete writeXxx/readXxx parameter names aligned
to the abstract ($bool / $byte / $i16 / etc. instead of $value) so
named-arg callers work uniformly. Fixed TTYPE::BOOL typo to TType::BOOL.
* TBinaryProtocol: same trans->write(..., len) cleanup; reads/writes
match the abstract signatures verbatim.
* StoredMessageProtocol::readMessageBegin matches TProtocolDecorator's
new typed signature.
* phpstan-baseline.neon: removed four "return statement is missing"
suppressions that are now resolved.
Tests:
* TBinaryProtocolTest / TCompactProtocolTest: dropped the vestigial
byte-count second element from `->with(buf, N)` mock argument
matchers and from data providers, because TTransport::write is
single-arg.
* TCompactProtocolTest::testWriteByte/testWriteUByte data: removed
the 'lowercase'/'upercase' cases that documented PHP's pre-strict
silent string->int coercion (`'a'` -> 0); writeByte/writeUByte now
require an int caller-side.
* TCompactProtocolTest::testWriteFieldBegin 'list' case updated
expectedBoolFid null -> 0 to match the typed int default.
* TProtocolDecoratorTest consolidated: write decoration data-provider
unchanged; the eight per-read-method tests collapsed to one
testReadMethodDecoration driven by an (name, argCount) data provider.
setUp() builds the decorator once and reuses it across tests.
* TSimpleJSONProtocolTest::testRead replaced the 10-case shape switch
with arity-based dispatch (array_fill + spread); cuts ~50 lines.
Generated-by: Claude Opus 4.7
* THRIFT-5983: Replace switch with match in PHP TProtocol::skip / skipBinary (#3463)
Client: php
Convert both type dispatchers in lib/php/lib/Protocol/TProtocol.php from
switch to match expressions:
- skip() — match over TType constants, delegating compound types
(STRUCT/MAP/SET/LIST) to dedicated private helpers since match
arms must be single expressions.
- skipBinary() — same pattern; merges arms with identical fixed-byte
sizes (BOOL/BYTE, I64/DOUBLE, SET/LST) for compactness.
Match expressions use strict comparison (===), forbid fall-through, and
return values directly — eliminating the manual `return` boilerplate.
Behavior is preserved; existing TProtocolException for unknown types
remains as the default arm.
Generated-by: Claude Opus 4.7
* THRIFT-5984: Cache function_exists() capability checks in PHP runtime (#3464)
Client: php
Memoize PHP capability probes that previously ran on every hot call:
- TBinarySerializer::serialize / deserialize — previously called
function_exists('thrift_protocol_{write,read}_binary') on every
invocation. Now cached via static nullable bool flags +
hasAcceleratedWrite() / hasAcceleratedRead() helpers using the
null-coalescing assignment (??=) operator.
- TSocket::open — previously called function_exists() twice per
open() to detect the sockets extension. Cached via
hasSocketsExtension() helper.
- TSocketPool — replace per-instance $useApcuCache property with
static $hasApcuCache + hasApcuCache() helper for consistency with
the rest of the cleanup. APCu availability is a process-level
property, not per-pool.
Each helper performs the check at most once per PHP process. Pure
optimization — no behavior change.
Tests:
- Add cache resets in setUp() of TBinarySerializerTest, TSocketTest,
TSocketPoolTest via reflection so mocked function_exists is
re-evaluated per test method.
- Register lib/php/src/ext/thrift_protocol/php_thrift_protocol.stub.php
in phpstan.neon scanFiles so PHPStan knows about the C-extension
functions guarded by the new helpers (previously the inline
function_exists() gave PHPStan a narrowing hint that the helper
hides).
Part of the umbrella ticket THRIFT-5960 (PHP modernization).
Generated-by: Claude Opus 4.7
* THRIFT-5985: Add native method types to PHP Exception hierarchy (#3465)
Client: php
Type the public surface of the PHP exception hierarchy in
lib/php/lib/Exception/:
- TException::__construct(string|array|null $p1 = null, int|array $p2 = 0)
— preserves the bridge constructor that accepts either standard
Exception args (message, code) or Thrift Base spec/vals via union
types.
- TApplicationException — typed __construct(?string $message, int $code)
plus read()/write() with TProtocol parameter and int return.
- TProtocolException — typed __construct(?string $message, int $code).
- TTransportException — typed __construct(?string $message, int $code).
The internal serialization helpers (readMap/writeMap/readList/...)
mirror TBase's untyped helpers and are left untouched here; typing
those is a separate concern.
Part of the umbrella ticket THRIFT-5960 (PHP modernization).
Generated-by: Claude Opus 4.7
* THRIFT-5989: Work around JWT-format GITHUB_TOKEN breaking composer install
Client: php
GitHub is rolling out a new GITHUB_TOKEN format (ghs_<id>_<jwt>) that
contains dots. shivammathur/setup-php passes this token verbatim to
composer config --global github-oauth.github.com. Composer's token
validator (BaseIO.php:143) rejects any token containing characters
outside [A-Za-z0-9-_], causing composer install to fail with:
Your github oauth token for github.com contains invalid characters
Set COMPOSER_AUTH='{}' as an environment variable on both composer
install steps (lib-php matrix and cross-test). This env var is the
highest-priority Composer auth source and overrides the invalid token
that setup-php wrote into the global config, without touching the
action pin.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Generated-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* THRIFT-5988: PHP 8.1 follow-up: float constants, README, and API compat (#3468)
Client: php
Replace magic float literals with PHP_FLOAT_MAX / PHP_FLOAT_MIN /
PHP_FLOAT_EPSILON in BoundaryValuesTest and remove the stale TODO that
was waiting for the PHP 7.1 floor to be dropped.
Update lib/php/README.md to state the correct minimum PHP version (8.1).
Restore TSSLServerSocket::getSSLHost() as a @deprecated public method
so that existing subclasses and callers are not silently broken by the
rename to the private ensureSslHostPrefix(). The shim delegates to the
private method and carries a notice that it will be removed in a future
release.
Generated-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* THRIFT-5987: Fix PHP protocol type-safety bugs in readBool and popContext (#3467)
Client: php
TCompactProtocol::readBool passes a ?bool& reference directly to
readByte(?int&), causing an integer to be stored in a bool-typed variable
when reading from container context. Fix routes through a local ?int
variable and explicitly casts to bool before assignment.
TJSONProtocol::popContext assigns the result of array_pop() (which is
BaseContext|null) to the non-nullable BaseContext $context property,
causing a TypeError on any context-stack underflow. Fix uses null
coalescing to fall back to a fresh BaseContext() if the stack is empty.
TCompactProtocolTest::testWriteListBegin and testWriteSettBegin omit
the $size argument from the writeCollectionBegin mock expectation,
leaving size-forwarding unverified. Restore ->with(TType::STRING, 1).
Generated-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* THRIFT-5986: Emit declare(strict_types=1) in PHP generator output (#3466)
Client: php
Add `declare(strict_types=1);` to every PHP file emitted by
t_php_generator (placed after the autogen license docblock, before
the namespace/use block — matching PSR-12 header order).
PHP arrays silently coerce numeric-string keys to int (e.g. `'123'`
becomes `123`) when used in `foreach`. Under strict types the typed
`writeXxx()` library calls then refuse those coerced values. Cast the
iterator variable back to its declared base type before the write
call in two places that take the array key:
- `generate_serialize_map_element` — map keys.
- `generate_serialize_set_element` — scalar set elements (sets are
stored as `[$elem => true]`, so the element is the array key).
The cast logic is centralized in a single new helper,
`emit_array_key_recast`, which only acts on `TYPE_STRING` and the
int family — other base types either can't be array keys or
round-trip through PHP's coercion losslessly.
Fixtures under `lib/php/test/Resources/packages/` are git-ignored and
regenerated by `make stubs` in CI, so no fixture files appear in this
diff.
Part of the umbrella ticket THRIFT-5960 (PHP modernization), phase G1.
Follow-ups in scope:
- G2: emit native return types on read/write/getName/validators.
- G3: emit native types on properties + constructor parameters.
Generated-by: Claude Opus 4.7
* THRIFT-5989: Work around JWT-format GITHUB_TOKEN breaking composer install
Client: php
Follow-up to #3469: COMPOSER_AUTH='{}' only overrides Composer's local
auth.json. The global auth.json written by shivammathur/setup-php (which
holds the invalid JWT token) is validated independently and before the
env var takes effect.
Explicitly unset the global github-oauth entry before each composer
install call (lib-php matrix and cross-test), removing the bad token at
the source.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Generated-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* Update build.yml
The composer config --global --unset approach hits a chicken-and-egg: Composer loads ~/.composer/auth.json via BaseIO::loadConfiguration and validates the token format before dispatching to any subcommand — including config --unset. So the very
command meant to remove the bad token can't run while the bad token is in place.
* THRIFT-5990: Emit native return types on generated PHP struct methods (#3472)
Client: php
Phase G2 of THRIFT-5960 PHP modernization. The PHP code generator
now emits native return types on the public struct surface:
- getName(): string
- read(TProtocol $input): int / read($input): int for binary_inline
mode (which reads from a raw TTransport buffer, not a TProtocol)
- write(TProtocol $output): int / write(string &$output): int for
binary_inline mode
- validateForRead(): void / validateForWrite(): void
- jsonSerialize(): mixed (drops the now-unnecessary
#[ReturnTypeWillChange] attribute since the project targets PHP 8.1+)
To make the TProtocol parameter type on read/write compatible with
LSP for generated subclasses extending TBase, the abstract signatures
on `TBase::read` / `TBase::write` are tightened in lock-step:
abstract public function read(TProtocol $input): int;
abstract public function write(TProtocol $output): int;
Three hand-written test fixtures extending TBase
(TestSerializerStruct, ComplexStruct, NestedStruct) are updated to
match the new TBase signatures. Generator fixtures under
lib/php/test/Resources/packages/ are git-ignored and regenerated by
`make stubs` in CI.
Generated-by: Claude Opus 4.7
* THRIFT-5991: Emit native types on generated PHP struct properties and constructor (#3473)
Client: php
Phase G3 of THRIFT-5960 PHP modernization. The PHP code generator
now emits native PHP types on struct property declarations and the
constructor parameter:
public ?int $errorCode = null; // was: public $errorCode = null;
public ?string $message = null;
public ?\Namespace\StructName $inner = null;
public ?array $items = null;
public function __construct(?array $vals = null)
Thrift-to-PHP base type mapping (all fields default nullable):
bool -> ?bool
byte / i8 / i16 / i32 / i64 -> ?int
double -> ?float
string / binary / uuid -> ?string
enum -> ?int
list / set / map -> ?array
struct / exception -> ?\Namespace\ClassName
Added the helper `type_to_native` that produces these declarations.
It deliberately omits the leading `?` so callers can place the
nullable marker as needed; for now the field/parameter sites pin all
emitted types to `?T` because Thrift fields default to null.
Exception subclasses inherit `$message` and `$code` (untyped) from
`\Exception`, and PHP forbids re-typing an inherited property. The
generator skips the native type emission for those two field names
in exception classes.
Generator fixtures under `lib/php/test/Resources/packages/` are
git-ignored and regenerated by `make stubs` in CI; no fixture files
appear in this diff.
Generated-by: Claude Opus 4.7
* THRIFT-5995: Add native method types to TBase / TException internal helpers (#3474)
Client: php
Type the protected/private serialization helpers shared by TBase and
its HackTown duplicate on TException:
readStruct(string $class, array $spec, TProtocol $input): int
writeStruct(string $class, array $spec, TProtocol $output): int
readMap(mixed &$var, array $spec, TProtocol $input): int
readList(mixed &$var, array $spec, TProtocol $input, bool $set = false): int
writeMap(array $var, array $spec, TProtocol $output): int
writeList(array $var, array $spec, TProtocol $output, bool $set = false): int
The by-ref read variants use `mixed &$var` because callers commonly
pass an uninitialised local (or `null`) which the helper fills with an
array; PHP forbids re-typing a non-mixed reference once bound. The
write variants pin `$var` to `array` since callers always pass a PHP
array for map / set / list values.
Adds the `use Thrift\Protocol\TProtocol;` import to TException (TBase
already had it from earlier work) and re-orders TException imports to
the standard alphabetical grouping.
Completes the in-library typing pass started by THRIFT-5981 (TProtocol)
and THRIFT-5985 (TException public surface). Part of umbrella
THRIFT-5960.
Generated-by: Claude Opus 4.7
* THRIFT-5992: Fix missing interface import at service impl
* THRIFT-5992: Fix Haxe generator keyword/reserved-type escaping and Linux test script
Client: haxe
- Add escape_haxe_keyword() to escape 45 Haxe reserved keywords as identifiers
- Extend get_cap_name() to append _ when name conflicts with Haxe stdlib types
- Fix haxe_thrift_add_import() to skip base-type typedefs (no Haxe class generated)
- Fix generate_reflection_getters/setters FIELD_ID constant name mismatch
- Fix run-Haxe-Codegen-Tests.ps1 for Linux/macOS path compatibility
- Update $KNOWN_BUGS: JavaDeepCopyTest, JavaTypes (unfixable Java-specific fixtures),
Thrift5320 (tracked as THRIFT-5993)
- Result: 201/201 tests pass (3 FAIL_THRIFT skips, 3 known bugs)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Generated-by: Claude Sonnet 4.6
* THRIFT-5993: Fix Haxe generator same-named cross-package type import shadowing
Client: haxe
- Fix haxe_thrift_add_import() to suppress imports whose short name matches
the entity being defined (service/struct), preventing foreign same-named
types from shadowing the local definition (THRIFT-5993)
- Also suppress duplicate short-name imports to avoid unresolvable ambiguity
when multiple packages export identically-named types
- Add make_haxe_user_type_name() helper with extended reserved-type list that
includes Haxe base type names (String, Bool, Float, Int, Void); applied at
struct/enum file names, class headers, import generation, and type_name()
branches so user-defined types named after Haxe built-ins are safely renamed
- Remove Thrift5320.thrift from $KNOWN_BUGS (now fixed); update JavaTypes and
JavaDeepCopyTest comments to reflect only the remaining ObjectMap<Float>
key-type constraint issue
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Generated-by: Claude Sonnet 4.6
* THRIFT-5993: Apply make_haxe_user_type_name to service file and class names
Client: haxe
Extend the base-type-name collision fix to service-level naming sites.
All generate_service_{interface,client,server} and generate_service() calls
that previously used get_cap_name(service_name_) now use
make_haxe_user_type_name(service_name_), keeping service file names, class
and interface headers, _iface_ type annotations, and import lines consistent
with the renamed type as returned by type_name() for cross-package references.
No test IDL exercises this path (no service named String/Bool/Float/Int/Void
exists in the tree), but the fix ensures correctness for the edge case.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Generated-by: Claude Sonnet 4.6
* THRIFT-5994: Fix Haxe generator for bool/double/binary map and set key types
Client: haxe
- Add BoolMap<T>/BoolSet: Bool key type encoded as 0/1 in IntMap/IntMap
- Add FloatMap<T>/FloatSet: Float key type stored as 8-byte IEEE 754 hex in
StringMap for exact equality semantics (correctly round-trips NaN, -0.0,
infinities)
- Add BytesMap<T>/BytesSet: Bytes key type stored as hex in StringMap for
content equality (ObjectMap/ObjectSet would give reference equality)
- Wire the new types in type_name(): map<bool,V> -> BoolMap, map<double,V> ->
FloatMap, map<binary,V> -> BytesMap; set<bool> -> BoolSet, set<double> ->
FloatSet, set<binary> -> BytesSet
- Clear $KNOWN_BUGS: JavaTypes.thrift and JavaDeepCopyTest.thrift now pass
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Generated-by: Claude Sonnet 4.6
* THRIFT-5997: Fix netstd generator: binary and UUID consts must use static readonly
Client: netstd
C# does not allow `const` for byte[] or Guid types. The generator
unconditionally emitted `public const` for all base types, causing
CS0283/CS0134 compile errors for Thrift fields of type binary or uuid.
Also improves the netstd codegen test script: fix cross-platform paths,
detect cmake-built thrift compiler, expand NET_VERSIONS to net8/9/10,
and reduce KNOWN_BUGS/FAIL_THRIFT to accurately reflect current state.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* THRIFT-5998: Fix netstd generator: duplicate extension methods from included programs
Client: netstd
When a Thrift IDL file included another, collect_extensions_types()
recursed into structs from the included program, causing the same
container extension methods (DeepCopy, Equals, GetHashCode) to be
emitted in both files. This produced CS0121 "ambiguous call" errors at
C# compile time.
Fix: stop recursion at program boundary. Each program's generator only
walks its own structs; the included program's generator handles theirs.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* THRIFT-5000: Restore Docker Official Image packaging
Client: docker
Co-Authored-By: OpenAI Codex (GPT-5.4) <codex@openai.com>
* THRIFT-6003: Add Haxe codegen test script and GitHub Actions CI job
Client: haxe
Tests the Haxe code generator by compiling every .thrift file in the
repository against the local Thrift library (via haxelib dev) for the
html5/JS target. The PowerShell script supports optional parameters for
output folder and extra IDL search path, keeping local dev behaviour
unchanged when called without arguments.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* THRIFT-6003: Add Haxe codegen test script and GitHub Actions CI job
Client: haxe
Fix: install Haxe via apt (krdlab/setup-haxe not on ASF allowlist);
add compiler/cpp to PATH so FindThriftExe can locate downloaded binary
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* THRIFT-6003: Add Haxe codegen test script and GitHub Actions CI job
Client: haxe
Fix: run haxelib setup before haxelib install (apt install does not initialise the repo)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* THRIFT-6001: Type remaining core PHP lib methods and fix TException tmethod UUID drift (#3480)
Client: php
Type the remaining untyped methods across core lib classes and fix two
real defects surfaced by the audit:
REAL BUG FIXES
- TException::$tmethod was missing `TType::UUID => 'Uuid'`, which TBase
has had since THRIFT-5980. Effect: UUID-typed fields in Thrift
`exception` structs fell through to the slow recursive STRUCT path
instead of the scalar fast-path during read/write. Added a unit test
guarding parity between the two maps to prevent future drift.
- TMultiplexedProcessor::process(TProtocol $input, TProtocol $output)
now declares `: mixed` (return value is propagated from the dispatched
underlying processor, whose return shape is generator-emitted; tightens
to `: bool` once the generator passes through PR-3).
TYPING
- TBase::__construct(?array $spec = null, ?array $vals = null)
- TBase::__wakeup(): void
- ThriftClassLoader::registerNamespace(string, string|array): void
- ThriftClassLoader::registerDefinition(string, string|array): void
- ThriftClassLoader::register(bool $prepend = false): void
- ThriftClassLoader::loadClass(string $class): void
- ThriftClassLoader::findFileInApcu(string $class): ?string
(corrects the previous loose contract; apcu_fetch returns false on
cache-miss, so we coerce to null to match the nullable return)
- TSocketPool::apcuFetch(string $key, ?bool &$success = null): mixed
- TSocketPool::apcuStore(string $key, mixed $var, int $ttl = 0): bool
- TConstant::get(string $constant): mixed
Follow-up to THRIFT-6000 within the umbrella THRIFT-5960
(PHP modernization).
Generated-by: Claude Opus 4.7
* THRIFT-6000: Add native types to PHP JSON protocol helpers and contexts (#3479)
Client: php
Type the remaining untyped methods in TJSONProtocol, TSimpleJSONProtocol,
their JSON/SimpleJSON Context classes, LookaheadReader, and
CollectionMapKeyException. All internal/protected helpers; no public API
change beyond the signature tightening.
Typed:
- TJSONProtocol::getTypeNameForTypeID(int $typeID): string
- TJSONProtocol::getTypeIDForTypeName(string $name): int
- TJSONProtocol::pushContext(BaseContext $c): void
- TJSONProtocol::__construct(TTransport $trans)
- TJSONProtocol::reset(): void
- TJSONProtocol::readJSONSyntaxChar(string $b): void
- TJSONProtocol::writeJSONString(mixed $b): void
- TJSONProtocol::writeJSONInteger(int $num): void (return only)
- TJSONProtocol::writeJSONObjectStart/End/ArrayStart/End(): void
- TJSONProtocol::readJSONString(bool $skipContext): mixed
- TJSONProtocol::readJSONNumericChars(): string
- TJSONProtocol::readJSONInteger(): int
- TJSONProtocol::readJSONIntegerAsString(): string
- TJSONProtocol::readJSONDouble(): float
- TJSONProtocol::readJSONObjectStart/End/ArrayStart/End(): void
- TSimpleJSONProtocol::pushWriteContext(Context $c): void
- TSimpleJSONProtocol::popWriteContext(): void (returns to default Context()
on stack underflow rather than null, matching the non-null property type)
- TSimpleJSONProtocol::assertContextIsNotMapKey(string $invalidKeyType): void
- TSimpleJSONProtocol::writeJSONString(mixed $b): void
- TSimpleJSONProtocol::writeJSONInteger(int $num): void
- JSON\\BaseContext, ListContext, PairContext, LookaheadReader,
SimpleJSON\\Context, ListContext, MapContext, StructContext:
all read()/write()/escapeNum()/isMapKey()/__construct() typed.
- CollectionMapKeyException::__construct(?string $message = null)
Follow-up to THRIFT-5999 within the umbrella THRIFT-5960
(PHP modernization).
Generated-by: Claude Opus 4.7
* THRIFT-5999: Raise PHPStan level from 1 to 5 on PHP library (#3476)
Client: php
Step the lib/php/phpstan.neon level from 1 to 5 and address every issue
PHPStan surfaces along the way.
Real fixes
----------
- TBinaryProtocol::readI64 — cast $arr[1] / $arr[2] to int before
bitwise-NOT on 32-bit hosts. unpack('N2', …) is documented to return
ints but the return type is array|false; the explicit casts silence
PHPStan and document intent.
- TSocket::write — drop dead `$written === -1` branch from the
post-fwrite() check. fwrite returns int|false, never -1, so the
comparison was strict-false at every call.
- ThriftClassLoader::findFile — convert return type to ?string (was
documented `string` but the body has an empty `return;` for the
"wrong call" path) and change `return;` / fall-through to explicit
`return null;`. Drops a `#HOW TO TEST THIS?` rhetorical comment.
- TMultiplexedProcessor::registerProcessor — type the parameters
(string $serviceName, object $processor) : void and reformat the
Javadoc-style @param tags to PHP convention.
Defensive dead-code baseline
----------------------------
The non-scalar map-key path in TBase::writeMap / TException::writeMap
mirrors the Thrift IDL `map<Struct|Map|List|Set, V>` semantics, but
PHP arrays only admit int|string keys, so this arm is unreachable
runtime. Baseline four corresponding messages with an explanatory
comment.
The pre-existing ThriftClassLoader::findFile baseline entry is removed
since the real fix above closes it.
Final phase of the umbrella THRIFT-5960 PHP modernization.
Generated-by: Claude Opus 4.7
* THRIFT-6002: Add netstd codegen test script and GitHub Actions CI matrix job
Client: netstd
Tests the netstd code generator by compiling every .thrift file in the
repository against the Thrift library for .NET 8, 9, and 10 via a
matrix CI job. The PowerShell script supports optional parameters for
target versions, output folder, and extra IDL search path, keeping
local dev behaviour unchanged when called without arguments.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* THRIFT-6006: Implement MESSAGE_SIZE_LIMIT exception type for Haxe library
Client: haxe
- Add CORRUPTED_DATA = 5 and MESSAGE_SIZE_LIMIT = 6 to TTransportException
- Replace END_OF_FILE throws with MESSAGE_SIZE_LIMIT in TEndpointTransport
for ResetConsumedMessageSize, CheckReadBytesAvailable, CountConsumedMessageBytes
- Improve error messages to include the configured limit and actual byte counts
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* THRIFT-6007: Implement MESSAGE_SIZE_LIMIT exception type for Delphi library
Client: delphi
- Add MessageSizeLimit to TExceptionType enum in TTransportException
- Add TTransportExceptionMessageSizeLimit class with GetType implementation
- Handle MessageSizeLimit in the deprecated Create factory method
- Replace TTransportExceptionEndOfFile throws with TTransportExceptionMessageSizeLimit
in TEndpointTransportBase: ResetMessageSizeAndConsumedBytes, CheckReadBytesAvailable,
CountConsumedMessageBytes
- Improve error messages to include the configured limit and actual byte counts
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* THRIFT-6005: Raise PHPStan level from 5 to 6 on PHP library (#3484)
Client: php
Step lib/php/phpstan.neon level from 5 to 6 and address every issue
PHPStan surfaces along the way.
Library typing fixes
--------------------
* TBinarySerializer::serialize(object $object): string
* TBinarySerializer::deserialize(string $string_object, class-string
$class_name, int $buffer_size = 8192): object
* TServer::__construct(object $processor, ...)
* TSocket / TSSLSocket __construct: documented $debugHandler as
callable|string|null via PHPDoc.
* TSocketPool::__construct: tightened to (array $hosts, int|array
$ports, bool $persist, ...) with list shape PHPDoc.
* TJSONProtocol static array properties get a native `array` declaration
plus `@var` element-type docblocks.
* TBase / TException internal helpers — readMap, readList, readStruct,
writeMap, writeList, writeStruct, __construct, plus TException bridge
ctor — gain `@param array<...>` shape documentation so PHPStan can
reason about $spec / $vals / $var element types.
Bug fixes
---------
* TBase::__wakeup() previously round-tripped through
$this->__construct(get_object_vars($this)). That call short-circuited
inside the body (second parameter was null) but tripped strict-mode
type checks under tighter array-shape PHPDoc. PHP restores object
state automatically on unserialize, so the body is now empty with a
comment.
* ThriftClassLoader::findFileInApcu() now uses a clear two-step
fetch-or-recompute pattern and narrows the return via is_string(),
eliminating the unreachable else-arm flagged by PHPStan.
Baseline regex updated to match the new "expects array<int|string,
mixed>, int|string given" wording for the four unreachable dead-code
arms in TBase / TException writeMap that mirror Thrift IDL `map<Struct,
V>` semantics PHP arrays cannot represent.
Final phase of the umbrella THRIFT-5960 PHP modernization.
Generated-by: Claude Opus 4.7
* THRIFT-6004: Emit native types on generated PHP service-level methods (#3483)
Client: php
Update t_php_generator to emit native PHP parameter and return types on
all generated service-level code:
* Interface (*If.php): public methods now declare typed params and
return — `foo(?string $thing): ?string`.
* Client (*Client.php): typed constructor
`__construct(TProtocol $input, ?TProtocol $output = null)`; typed
`$input`/`$output`/`$seqid` properties; typed RPC methods, typed
`send_*` (synthetic t_function with g_type_void return), typed
`recv_*` (already synthetic; now inherits the parent
function_signature return-type machinery).
* Processor (*Processor.php): typed
`__construct(object $handler)`; typed
`protected ?object $handler_ = null`; typed
`process(TProtocol $input, TProtocol $output): bool` (changed the
early "method not found" `return;` to `return false;` to satisfy the
declared return type); typed
`process_NAME(int $seqid, TProtocol $input, TProtocol $output): void`.
* Rest (*Rest.php): typed `__construct(object $impl)`; typed
`protected object $impl;`; typed method signatures
`methodName(array $request): ?T`; emit `return` only when the
underlying impl method returns non-void.
Implementation
--------------
* New helper `type_to_return(t_type*)` renders `: void` or `: ?T` for
return-type clauses, sharing the existing `type_to_native()` mapping.
* `function_signature()` extended to append `type_to_return()` for the
return type; `argument_list()` extended to emit `?type_to_native()`
on every parameter (previously only struct/container types were
typed).
* `send_*` emission now constructs a synthetic
`t_function(g_type_void, ...)` so `function_signature()` produces
the correct `: void` for the writer half of the RPC.
Drive-by cleanup
----------------
`ThriftClassLoader::findFileInApcu()` (merged in THRIFT-6001) was
flagged by PHPStan: the trailing `$file !== false ? $file : null`
arm is unreachable because the if-branch reassigns `$file` to the
findFile() result (`?string`). Rewrote the body to a clear two-step
fetch-or-recompute and narrowed the return through `is_string()` to
satisfy the analyser without relying on a phantom else-arm.
Generated fixtures regenerate via `make stubs` in CI; nothing
checked in changes.
Part of umbrella THRIFT-5960 (PHP modernization).
Generated-by: Claude Opus 4.7
* THRIFT-6008: Add regression tests for recent PHP fixes (#3489)
Client: php
Add targeted unit tests guarding three recently-fixed bugs whose code
paths had no direct test coverage:
* THRIFT-6001 — TException::tmethod previously omitted TType::UUID, so
UUID-typed fields in exception structs fell through to the recursive
STRUCT path on write. Extend the TestRichException fixture with a
uuidField (TType::UUID) and add a 'uuid' yield to
TExceptionTest::writeAndReadFieldDataProvider, asserting the value
round-trips intact through TBinaryProtocol.
* THRIFT-5987 — TCompactProtocol::readBool in STATE_CONTAINER_READ
previously passed its `?bool &$bool` reference straight into
readByte(?int &$byte), leaving the caller's variable holding the raw
int. Add testReadBoolInContainerState with three data-provider rows
(0 → false, 1 → true, 0x7f → true) that mock TTransport, force
STATE_CONTAINER_READ via reflection, and assert the value comes back
as a real PHP bool.
* TJSONProtocol::popContext underflow recovery — when the `$context`
property was tightened to non-nullable (THRIFT-5981/5985), popContext()
was patched to fall back to `new BaseContext()` instead of returning
null. Add testPopContextOnEmptyStackFallsBackToBaseContext that
reflects into the private method and asserts the property holds a
BaseContext after popping an empty stack — no TypeError.
Validation: phpcs 0 errors, phpstan level 5 0 errors, 642 unit tests
(+5 new) and 108 integration tests pass.
Part of umbrella THRIFT-5960 (PHP modernization).
Generated-by: Claude Opus 4.7
* Update to setup-php 2.37.1
* THRIFT-5996: connection check supports TLS sockets
Client: go
The connection check introduced in THRIFT-5214 now supports
TLS connections using a technique from the code that
initially inspired the check:
https://github.com/go-sql-driver/mysql/pull/934
Testing done: new test with alongside the existing test of conn. check
* Update ReleaseManagement.md
Releases now `release/NN.NN.NN`
* THRIFT-5954: add read/write timeout support to Rust TTcpChannel
* Updated projects settings in .asf.yaml (features, merge buttons, Jira autolinking) [skip ci]
* Set up default protection ruleset for default and release branches
* THRIFT-6011: Make compiled Go code formatting compatible with gofmt
* Add generator paths to mergeable labels
Co-Authored-By: OpenAI Codex (GPT-5.4) <codex@openai.com>
* Bump golang.org/x/sys to 0.0.0-20220412211240-33da011f77ad
* THRIFT-5802: Validate set uniqueness in Node.js library
A Thrift set is defined to contain unique elements, but currently
different language implementations have handled duplicate elements
inconsistently: Go throws, Python silently deduplicates, while Node.js
passed duplicates through unchanged, breaking cross-language interop.
Add duplicate-element validation in the JavaScript code generator and
runtime libraries:
* lib/nodejs/lib/thrift/thrift.js, lib/js/src/thrift.js: new
Thrift.checkSetUniqueness(arr) helper. Duplicate detection via a
native JS Set; throws TProtocolException(INVALID_DATA) on the first
duplicate. Both the Node.js and the browser/ES6/TS runtime libraries
are updated, since the JS code generator emits the same
Thrift.checkSetUniqueness call regardless of target.
* compiler/cpp/src/thrift/generate/t_js_generator.cc: in
generate_serialize_container() emit a Thrift.checkSetUniqueness call
immediately before output.writeSetBegin(), so the validation runs
before any bytes hit the transport. In
generate_deserialize_container() for sets, allocate one parallel
`new Set()` before the per-element loop; in
generate_deserialize_set_element() guard the push with
seen.has(elem) / seen.add(elem).
* lib/nodejs/test/check_set_uniqueness.test.js,
lib/nodejs/test/testAll.sh: new tape unit tests covering unique
sets, duplicate sets across primitive types, empty/single-element
edge cases, and the thrown exception type.
* THRIFT-5949: Add default timeout to Ruby server sockets
* THRIFT-6014: Add recursion depth limit to skip() in JavaScript library
Client: js
Aligns the browser JavaScript library skip() with the Node.js protocols
(binary, compact, JSON), which already enforce a depth limit of 64.
Adds a depth parameter and throws TProtocolException with DEPTH_LIMIT
when depth exceeds 64. Adds a QUnit test harness covering the boundary.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Fix netstd CI .NET SDK setup
Use the pinned setup-dotnet action instead of downloading and verifying the dotnet-install script manually. The manual path fails when the hosted script signature does not match the downloaded script.
Co-Authored-By: OpenAI Codex (GPT-5.4) <codex@openai.com>
* THRIFT-6013: Add recursion depth limit to skip() in Ruby library
Client: rb
Aligns the Ruby skip() implementation with Java, Python, Go and netstd,
which already enforce a configurable recursion depth limit. Adds a
max_depth parameter (default 64) and raises ProtocolException::DEPTH_LIMIT
when exceeded.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* THRIFT-6012: Fix inverted regexp.MatchString arguments and precompile patterns in Go validator
Client: go
Replace inline regexp.MatchString calls with precompiled
regexp.MustCompile variables for literal vt.pattern annotations.
This avoids recompiling the same regex on every Validate() call.
Also fixes two bugs in the original regexp.MatchString usage:
- Arguments were swapped: MatchString(target, pattern) instead
of MatchString(pattern, target)
- Used ; ok instead of ; !ok, causing validation to fail when the
pattern matched instead of when it didn't
* THRIFT-6009: Add PSR-3 LoggerInterface support to PHP transports (#3490)
Client: php
* Require psr/log ^1 || ^2 || ^3. TSocket/TSSLSocket/TSocketPool
constructors accept a Psr\Log\LoggerInterface as $debugHandler.
The PSR-3 path is always invoked and the logger filters by level
(per-call-site DEBUG / WARNING / ERROR in TSocketPool::open()).
* Default with no handler is silent (NullLogger). When the caller
enables setDebug(true) without supplying a handler, log() falls
back to PHP error_log() — preserves master's stderr output.
* Legacy callable / string $debugHandler is preserved for BC;
constructor emits E_USER_DEPRECATED when used. setDebug() still
gates that legacy path and is itself @deprecated.
* TSSLServerSocket::getSSLHost() now emits E_USER_DEPRECATED.
* TestClient.php demonstrates the new API via a small PSR-3
StderrLogger.
* New Test\Thrift\Unit\Lib\UserDeprecationCapture trait factors
shared E_USER_DEPRECATED capture out of the unit tests.
Generated-by: Claude Opus 4.7
* THRIFT-6016: Move jsdoc from dependencies to devDependencies in lib/ts
Client: ts
jsdoc is a documentation generator and must not be a runtime dependency.
Having it under dependencies caused taffydb and lodash to be classified
as production transitive dependencies, inflating the vulnerability surface
of the published npm package.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Replace memory-safety asserts with unconditional throws in TBufferTransports
Client: cpp
Five assert() calls guarding memcpy operations and pointer arithmetic in
TBufferTransports.cpp are compiled out under -DNDEBUG (standard production
builds), silently removing the checks. Replace each with an unconditional
TTransportException(INTERNAL_ERROR) throw so a violated invariant is always
observable regardless of build flags. Remove the now-unused <cassert> include.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Generated-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* THRIFT-6017: Remove grunt-jsdoc and jsdoc dead dependencies from lib/ts
Client: ts,js
grunt-jsdoc@2.4.1 hard-depends on jsdoc ^3.6.x, which pulls in taffydb
(abandoned, HIGH vulnerability) regardless of the top-level jsdoc version.
The grunt-jsdoc task was never loaded in Gruntfile.js, and lib/ts has no own
source files to document, making both packages dead dependencies.
Remove grunt-jsdoc and jsdoc from devDependencies, drop the unreachable
`grunt jsdoc` body from the doc: Makefile.am target, and regenerate
package-lock.json. taffydb, its lodash transitive, and grunt-jsdoc are
fully eliminated from the dependency tree.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Generated-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* THRIFT-6019: Remove abandoned html-validator-cli devDependency
Client: js
html-validator-cli@2.0.0 (last published 2015) depends on
html-validator@0.0.8 which in turn depends on the deprecated
`request` package, pulling in vulnerable transitive dependencies
including tough-cookie@2.5.0, form-data, and qs.
The only consumer was the `check-local` target in test/Makefile.am,
which called the W3C remote HTML validation API. This target is not
exercised in GitHub CI (the autotools full-tree `make check` is not
wired into the CI workflow). The `if WITH_NODEJS` conditional is now
unnecessary, so the two branches are collapsed into a single
unconditional rule that retains the compiler's HTML generation
smoke-test.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Generated-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* Enforce RFC 6125 wildcard placement in TSSLSocket hostname matching
Client: cpp
Wildcards in certificate names must appear only in the leftmost
label per RFC 6125 §6.4.3. Add the check to matchName() and
cover it with a dedicated Boost.Test suite.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* THRIFT-6015: Add Ruby multiplexed default processor
* THRIFT-5310: Harden Ruby binary protocol integer bounds
* THRIFT-6018: Remove phantom and phantomjs-prebuilt from lib/ts
Client: ts,js
phantom@6.x pulls in phantomjs-prebuilt, which is an abandoned project
with known vulnerabilities. The qunit tests in lib/ts have already been
migrated to puppeteer (headless Chrome) via grunt-contrib-qunit, so the
phantom npm package has been dead weight since that migration.
Also removes the orphan lib/ts/test/phantom-client.ts file, which was a
leftover from the phantomjs era. The file used the phantomjs binary
globals API (phantom.page.injectJs, phantom.exit) and was never wired
into any grunt task, test runner, or build target. Removing it along
with @types/phantom is necessary to avoid a TypeScript compilation
error (tsc would pick it up from the test/ directory).
Note: lib/ts/test/build.xml still references the system phantomjs
binary for the legacy Ant-based test path; that is a separate cleanup.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Generated-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* THRIFT-6020: Fix npm audit vulnerabilities in lib/ts and lib/nodejs
Client: ts,js
lib/ts: bump grunt to ^1.6.2; add overrides for bn.js, brace-expansion,
grunt-legacy-log, grunt-legacy-log-utils, grunt-legacy-util, micromatch,
semver, trim-newlines. Reduces vulnerabilities from 18 to 8 (jshint->lodash
and elliptic chains have no available fix).
lib/nodejs (root): bump eslint to ^9.27.0; add overrides for @babel/helpers,
ajv, brace-expansion, debug, semver, underscore. Reduces vulnerabilities to 0.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Add peer hostname validation to c_glib TLS client
Client: c_glib
Sets SSL_set1_host() before SSL_connect() so the peer certificate CN/SAN
is validated against the hostname. Guarded with OPENSSL_VERSION_NUMBER
>= 0x10100000L since SSL_set1_host() was introduced in OpenSSL 1.1.0.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* No ticket: Clarify when the zigzag encoding is used.
Client: all
Patch: Andrew Bell
This closes #3503
* Remove Ruby known failures from cross-test list
* THRIFT-6010: Add PSR-18 HTTP transport (TPsrHttpClient) for PHP (#3492)
Client: php
TPsrHttpClient is a new HTTP transport backed by any PSR-18 ClientInterface,
with PSR-7/PSR-17 factories auto-discovered via php-http/discovery when not
explicitly injected. Concrete clients (Guzzle, Symfony HttpClient, php-http/
curl-client) are listed under composer "suggest".
Existing TCurlClient and THttpClient transports are left untouched.
Generated-by: Claude Opus 4.7 <noreply@anthropic.com>
* No ticket: change sprintf to snprintf to eliminate security warnings on OSX
Client: cpp
* Add decompressed byte tracking to C++ TZlibTransport
Client: cpp
TZlibTransport::read() called checkReadBytesAvailable() but never
called countConsumedMessageBytes(), so remainingMessageSize_ was never
decremented. Each read() call would pass the check regardless of how
many bytes had already been decompressed. Add countConsumedMessageBytes()
after each copy from the inflate buffer so that the TConfiguration
maxMessageSize limit is correctly enforced across the lifetime of a
decompression session.
Also adds test_message_size_limit() to ZlibTest to cover this path.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Add decompressed byte tracking to Java TZlibTransport
Client: java
TIOStreamTransport.read() does not call checkReadBytesAvailable() or
countConsumedMessageBytes(), so TZlibTransport inherited no limit
enforcement on decompressed bytes despite having a TConfiguration.
Override read() in TZlibTransport to check the pre-read budget and
count every decompressed byte against remainingMessageSize so that
maxMessageSize is enforced cumulatively across the full session.
Also adds testMessageSizeLimit to TestTZlibTransport covering this path.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Add decompressed size limit to Python TZlibTransport
Client: py
Adds max_decompressed_size parameter to TZlibTransport and
TZlibTransportFactory, defaulting to HARD_MAX_FRAME_SIZE (consistent
with THeaderTransport). readComp() now passes the remaining budget to
decompressobj.decompress() and raises TTransportException.SIZE_LIMIT
when unconsumed_tail is non-empty.
Also adds two test cases covering the new limit.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Add decompressed data size limit to TZlibTransport
Client: go
Enforce TConfiguration.GetMaxMessageSize() on decompressed bytes
read through TZlibTransport, consistent with the limit applied by
other transports in the Go library.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Add decompressed data size limit to TZlibTransport
Client: d
Enforce a configurable maximum on total decompressed bytes read
through TZlibTransport, consistent with the limit applied by
other transports in the library. The default is 100 MB.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Add consumed byte tracking to ThriftZlibTransport read
Client: c_glib
Call countConsumedMessageBytes() after each successful read so that
the pre-existing checkReadBytesAvailable() limit is decremented per
the transport's message size configuration.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* Bump uuid and nyc
Bumps [uuid](https://github.com/uuidjs/uuid) to 14.0.0 and updates ancestor dependency [nyc](https://github.com/istanbuljs/nyc). These dependencies need to be updated together.
Updates `uuid` from 3.4.0 to 14.0.0
- [Release notes](https://github.com/uuidjs/uuid/releases)
- [Changelog](https://github.com/uuidjs/uuid/blob/main/CHANGELOG.md)
- [Commits](https://github.com/uuidjs/uuid/compare/v3.4.0...v14.0.0)
Updates `nyc` from 15.0.0 to 15.1.0
- [Release notes](https://github.com/istanbuljs/nyc/releases)
- [Changelog](https://github.com/istanbuljs/nyc/blob/main/CHANGELOG.md)
- [Commits](https://github.com/istanbuljs/nyc/compare/v15.0.0...v15.1.0)
---
updated-dependencies:
- dependency-name: uuid
dependency-version: 14.0.0
dependency-type: indirect
- dependency-name: nyc
dependency-version: 15.1.0
dependency-type: direct:development
...
Signed-off-by: dependabot[bot] <support@github.com>
* THRIFT-6024: Use DEFAULT_MAX_FRAME_SIZE as default in Python THeaderTransport and TZlibTransport
Client: py
HARD_MAX_FRAME_SIZE (0x3FFFFFFF, ~1 GB) is a protocol-level structural
constraint, not a policy default. All other Thrift bindings default to
DEFAULT_MAX_FRAME_SIZE (16384000, ~16 MB). Python was inadvertently
using the hard cap as the constructor default, leaving applications
unprotected against oversized frames unless the caller explicitly called
set_max_frame_size().
Also fix a flake8 E303 (too many blank lines) in the TZlibTransport test.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* test
---------
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Volodymyr Panivko <sveneld@apache.org>
Co-authored-by: Jens Geyer <jensg@apache.org>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Jens Geyer <Jens-G@users.noreply.github.com>
Co-authored-by: Dmytro Shteflyuk <kpumuk@apache.org>
Co-authored-by: OpenAI Codex (GPT-5.4) <codex@openai.com>
Co-authored-by: Marin Nozhchev <murfffi@gmail.com>
Co-authored-by: Shem Shadrack <shemtorga@gmail.com>
Co-authored-by: The Apache Software Foundation <root-asf-gitbox-commits@apache.org>
Co-authored-by: RPC Tester <47292565+KantConnect@users.noreply.github.com>
Co-authored-by: Andrew Bell <andrew.bell.ia@gmail.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Add targeted unit tests guarding three recently-fixed bugs whose code paths had no direct test coverage. Pure additions — no library code changes.
Tests added
1. UUID round-trip in exception structs (guards THRIFT-6001)
TException::$tmethodpreviously omittedTType::UUID, so UUID-typed fields inexceptionstructs fell through to the slow recursive STRUCT path on write. Extended theTestRichExceptionfixture with auuidFieldand added a'uuid'yield toTExceptionTest::writeAndReadFieldDataProvider, asserting the value round-trips intact throughTBinaryProtocol.2. TCompactProtocol readBool in container state (guards THRIFT-5987)
In
STATE_CONTAINER_READ,readBool()previously passed its?bool &$boolreference straight intoreadByte(?int &$byte), leaving the caller's variable holding the raw int instead of bool. AddedtestReadBoolInContainerStatewith three data-provider rows (0 → false,1 → true,0x7f → true) that mockTTransport, forceSTATE_CONTAINER_READvia reflection, and assert the value comes back as a real PHP bool.3. TJSONProtocol popContext underflow recovery
When the
$contextproperty was tightened to non-nullable in THRIFT-5981 / 5985,popContext()was patched to fall back tonew BaseContext()instead of returning null. AddedtestPopContextOnEmptyStackFallsBackToBaseContextthat reflects into the private method and asserts the property holds aBaseContextafter popping an empty stack — no TypeError.Validation (Docker
thrift-php-dev:local)phpcs— 0 errorsphpstan(level 5) — 0 errorsphpunitUnit Suite — 642 tests, 0 failures (+5 new vs master's 637)phpunitIntegration Suite — 108 tests, 0 failuresPart of umbrella THRIFT-5960.
Generated-by: Claude Opus 4.7