Skip to content

Fix: prevent fatal TypeError in EditFormRoute when post ID is non-numeric#8247

Open
thisismyurl wants to merge 5 commits into
impress-org:developfrom
thisismyurl:fix/edit-form-route-non-numeric-post-id
Open

Fix: prevent fatal TypeError in EditFormRoute when post ID is non-numeric#8247
thisismyurl wants to merge 5 commits into
impress-org:developfrom
thisismyurl:fix/edit-form-route-non-numeric-post-id

Conversation

@thisismyurl

Copy link
Copy Markdown

Hey team,

Fixes #8229.

The bug

EditFormRoute::__invoke() calls abs($_GET['post']) after only checking ! is_array(). When another plugin (Contact Form 7 uses hexadecimal IDs like 5c80d03) opens an admin edit page, the admin_init hook fires globally, this route runs, and PHP 8.x throws:

TypeError: abs(): Argument #1 ($num) must be of type int|float, string given

because '5c80d03' is not numeric (is_numeric('5c80d03')false) and PHP 8 no longer coerces non-numeric strings in arithmetic functions.

The fix

Extend the existing guard with && is_numeric($_GET['post']) so the route body only runs when the value can safely be passed to abs(). Add an explicit (int) cast for type clarity:

- if ( ! is_array($_GET['post'])) {
-     $post = get_post(abs($_GET['post']));
+ if ( ! is_array($_GET['post']) && is_numeric($_GET['post'])) {
+     $post = get_post(abs((int) $_GET['post']));

Tests

Added tests/Feature/FormBuilder/EditFormRouteTest.php with two cases:

  • testInvokeWithNonNumericPostIdDoesNotThrowTypeError — sets $_GET['post'] = '5c80d03', invokes the route, asserts no TypeError is thrown. This is the delete-the-fix guard: removing is_numeric() causes abs('5c80d03') to throw on PHP 8.x, which the catch block catches and $this->fail() turns into a test failure.
  • testInvokeWithArrayPostIdIsSkipped — confirms the existing is_array() guard still works.

Changelog

Added changelog/fix-edit-form-route-non-numeric-post-id.md with Significance: patch, Type: fixed.

(full disclosure: AI helped me identify the issue and verify my work)

…fatal TypeError with non-numeric post IDs

Fixes impress-org#8229

abs() on a non-numeric string (e.g. Contact Form 7's hex post IDs) throws a fatal
TypeError on PHP 8.x. Add is_numeric() to the existing is_array() guard and cast
to int before passing to abs() for explicit type safety.
Copilot AI review requested due to automatic review settings June 17, 2026 13:48

Copilot AI left a comment

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.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Adds defensive input validation to the Form Builder’s edit route to prevent PHP 8 TypeErrors when $_GET['post'] is non-numeric (e.g., hex IDs), and introduces regression coverage + a changelog entry.

Changes:

  • Guard EditFormRoute against non-numeric $_GET['post'] before calling abs().
  • Add feature tests covering non-numeric and array post query values.
  • Add a changelog entry documenting the fix.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 9 comments.

File Description
tests/Feature/FormBuilder/EditFormRouteTest.php Adds regression tests to ensure EditFormRoute won’t TypeError on non-numeric/array post query values.
src/FormBuilder/Routes/EditFormRoute.php Adds numeric guarding + casts to int before calling abs()/get_post().
changelog/fix-edit-form-route-non-numeric-post-id.md Documents the patch fix and the affected scenario (e.g., Contact Form 7 hex IDs).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

class EditFormRoute
{
/**
* @since TBD Add is_numeric() guard to prevent fatal TypeError when post ID is non-numeric (e.g. Contact Form 7 hex IDs).
Comment on lines +27 to +28
if ( ! is_array($_GET['post']) && is_numeric($_GET['post'])) {
$post = get_post(abs((int) $_GET['post']));
// WP sends an array of IDs so if that is the case here, we can skip this
if ( ! is_array($_GET['post'])) {
$post = get_post(abs($_GET['post']));
if ( ! is_array($_GET['post']) && is_numeric($_GET['post'])) {
Comment on lines +31 to +32
$_GET['post'] = '5c80d03'; // Hexadecimal ID as used by Contact Form 7.
$_GET['action'] = 'edit';
'EditFormRoute threw a TypeError for non-numeric post ID: ' . $e->getMessage()
);
} finally {
unset( $_GET['post'], $_GET['action'] );
unset( $_GET['post'], $_GET['action'] );
}

$this->assertTrue( true, 'No TypeError was thrown for non-numeric post ID.' );
*
* @see https://github.com/impress-org/givewp/issues/8229
*
* @since TBD
* of type int|float, string given" on PHP 8.x, crashing every admin page that
* CF7 or similar plugins opened with a hex post ID in the query string.
*
* @since TBD
* Confirm that the route also handles an array post ID gracefully (the bulk
* action case that the original is_array() guard was written for).
*
* @since TBD
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Fatal TypeError in EditFormRoute.php: abs() called with non-numeric post ID on non-GiveWP admin pages (e.g. Contact Form 7)

3 participants