Skip to content

THRIFT-6047: Limit struct read/write recursion depth in PHP library#3552

Draft
Jens-G wants to merge 1 commit into
apache:masterfrom
Jens-G:php-recursion-depth
Draft

THRIFT-6047: Limit struct read/write recursion depth in PHP library#3552
Jens-G wants to merge 1 commit into
apache:masterfrom
Jens-G:php-recursion-depth

Conversation

@Jens-G
Copy link
Copy Markdown
Member

@Jens-G Jens-G commented May 28, 2026

Summary

  • Adds incrementRecursionDepth() / decrementRecursionDepth() to TProtocol
  • Limit is 64; throws TProtocolException(DEPTH_LIMIT) when exceeded
  • TBase::read / TBase::write wrap with try/finally to guarantee counter restoration
  • PHP generator emits the calls for all generated struct read/write methods

Test plan

  • lib/php/test/Unit/Lib/Protocol/TProtocolTest.php covers allow/reject/restore

🤖 Generated with Claude Code

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Client: php

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@sveneld sveneld left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Functionally solid — see two style nits inline. Will follow up on the binary_inline / integration-test items separately.

$fid = 0;
$input->incrementRecursionDepth();
try {
$xfer += $input->readStructBegin($fname);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Style: the try { ... } block body isn't indented relative to the surrounding code, so the body sits at the same column as try { itself. PSR-12 expects the body to be one level deeper. The same shape is in writeStruct below. CI is green only because phpcs doesn't enforce Generic.WhiteSpace.ScopeIndent for this rule, but visually it reads as if the try had no body. Suggest:

Suggested change
$xfer += $input->readStructBegin($fname);
$input->incrementRecursionDepth();
try {
$xfer += $input->readStructBegin($fname);

…and reindent the matched closing brace + every line in between.

$xfer = 0;
$output->incrementRecursionDepth();
try {
$xfer += $output->writeStructBegin($class);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same indent issue as in readStruct — body of try { is one level shallower than it should be.

}

public function testIncrementRecursionDepthThrowsAtLimit(): void
{
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: PHPUnit canonical way to express “the code under test must not throw and has no value to assert on” is $this->expectNotToPerformAssertions(); at the top of the test, rather than a trailing assertTrue(true). Same for testDecrementRecursionDepthRestoresCapacity below.

}

private function buildBinaryBuffer(callable $writer): string
{
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same nit — prefer $this->expectNotToPerformAssertions(); over assertTrue(true).

@Jens-G Jens-G marked this pull request as draft May 28, 2026 22:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants