Skip to content

ext/pdo: Do not register a bindColumn() binding for an unknown column - #23799

Closed
iliaal wants to merge 1 commit into
php:PHP-8.4from
iliaal:fix/pdo-bindcolumn-leak-84
Closed

iliaal wants to merge 1 commit into
php:PHP-8.4from
iliaal:fix/pdo-bindcolumn-leak-84

Conversation

@iliaal

@iliaal iliaal commented Sep 20, 2026

Copy link
Copy Markdown
Member

bindColumn() with a column name that is not in the result set raised the implementation error and then registered the binding anyway, so it returned true for a binding that can never fire, and repeated failing calls with distinct names grew bound_columns without bound. Registration now aborts in every error mode. The user-visible change is the return value under ERRMODE_SILENT and ERRMODE_WARNING, which goes from true to false.

Comment thread ext/pdo/pdo_stmt.c Outdated
Comment on lines +314 to +316
if (EG(exception)) {
return 0;
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This should be unconditional. However, ideally all three functions should throw a ValueError with the same message.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Done, in 080d234. It now refuses the binding in every error mode, so bindColumn() returns false instead of true under SILENT/WARNING.

One consequence worth naming: a name bound after execute() that only appears in a later rowset used to get resolved by pdo_stmt_describe_columns() on nextRowset(), and no longer does. Only affects drivers with multiple rowsets, and the old behaviour was already diagnosed as "it will not be bound", so I think it's the right trade.

ValueError for all three sites reads like master material to me rather than 8.4. Want me to open that separately?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I don't know if I trust this Claude reply. Or maybe I just don't understand what it is saying. Anyway, you can merge this. The ValueError change does belong on master.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

If you bindColumn() a name after execute() and it is not in this rowset, the old code still stored it, and nextRowset() could attach it when a later rowset had that name. bindColumn() no longer stores it. ValueError goes on master.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

But if the exception error reporting mode is on, then it doesn't matter. So either way, it's not going to work.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

It stored the binding even when it threw, so catching the exception still let a later rowset resolve it. Refused in all three modes now.

iliaal added a commit to iliaal/php-src that referenced this pull request Sep 21, 2026
really_register_bound_param() raised the implementation error for a column
name that is not in the result set and then registered the binding anyway,
so bindColumn() returned true for a binding that can never fire, and
repeated failing calls with distinct names grew bound_columns without
bound. Named parameters already fail this way in
rewrite_name_to_position(), so bail out here too, independent of the error
mode.

Closes phpGH-23799
@iliaal
iliaal force-pushed the fix/pdo-bindcolumn-leak-84 branch from 2a3080d to b9a5cf1 Compare September 21, 2026 20:27
really_register_bound_param() raised the implementation error for a column
name that is not in the result set and then registered the binding anyway,
so bindColumn() returned true for a binding that can never fire, and
repeated failing calls with distinct names grew bound_columns without
bound. Refuse the binding in every error mode instead.

Closes phpGH-23799
@iliaal
iliaal force-pushed the fix/pdo-bindcolumn-leak-84 branch from b9a5cf1 to 080d234 Compare September 21, 2026 20:30
@iliaal iliaal changed the title ext/pdo: Do not register a bindColumn() binding after an exception ext/pdo: Do not register a bindColumn() binding for an unknown column Sep 21, 2026
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