Skip to content

Avoid using a null alias as an array offset in getAliases()#658

Merged
williamdes merged 2 commits into
phpmyadmin:5.11.xfrom
ardittirana:fix-getaliases-null-array-offset
Jun 26, 2026
Merged

Avoid using a null alias as an array offset in getAliases()#658
williamdes merged 2 commits into
phpmyadmin:5.11.xfrom
ardittirana:fix-getaliases-null-array-offset

Conversation

@ardittirana

Copy link
Copy Markdown
Contributor

Resolves the phpmyadmin/sql-parser side of phpmyadmin/phpmyadmin#20313.

Problem

SelectStatement::getAliases() builds a table-alias map:

$tables[$thisDb][$expr->alias] = $expr->table;

for every FROM/JOIN expression. When a table has no alias, $expr->alias is null, so this uses null as an array offset, which is deprecated as of PHP 8.5:

Using null as an array offset is deprecated, use an empty string instead

phpMyAdmin surfaces this as an ErrorException (SelectStatement.php:614) during table export on PHP 8.5.

Fix

Skip expressions without an alias, mirroring the existing isset($expr->alias) && $expr->alias !== '' guards a few lines above. The null-keyed entry was never read anyway — the only consumer looks up $tables[$thisDb][$expr->table], whose offset is always a non-empty string — so getAliases() output is unchanged.

Notes

  • Removed the now-resolved PossiblyNullArrayOffset entry from psalm-baseline.xml (verified via psalm --update-baseline; only that entry changed).
  • The sibling report #20312 points at Utils/Misc.php, which no longer exists — getAliases() was moved into SelectStatement in Remove Misc class #454 — so this covers the live code path.

Tests

  • Added a getAliasesProvider case mixing an unaliased table with an aliased one (the null-alias path), asserting unchanged output.
  • Full suite green: 1020 tests, 10244 assertions. phpcs/psalm clean for the change.

Comment thread src/Statements/SelectStatement.php Outdated
@codecov

codecov Bot commented Jun 22, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 96.92%. Comparing base (4c45eac) to head (290d1de).

Additional details and impacted files
@@            Coverage Diff            @@
##             5.11.x     #658   +/-   ##
=========================================
  Coverage     96.92%   96.92%           
- Complexity     2316     2318    +2     
=========================================
  Files            71       71           
  Lines          5110     5112    +2     
=========================================
+ Hits           4953     4955    +2     
  Misses          157      157           
Flag Coverage Δ
unit-7.2-ubuntu-latest 96.92% <100.00%> (+<0.01%) ⬆️
unit-7.3-ubuntu-latest 96.91% <100.00%> (+<0.01%) ⬆️
unit-7.4-ubuntu-latest 96.89% <100.00%> (+<0.01%) ⬆️
unit-8.0-ubuntu-latest 96.91% <100.00%> (+<0.01%) ⬆️
unit-8.1-ubuntu-latest 96.91% <100.00%> (+<0.01%) ⬆️
unit-8.2-ubuntu-latest 96.87% <100.00%> (+<0.01%) ⬆️
unit-8.3-ubuntu-latest 96.87% <100.00%> (+<0.01%) ⬆️
unit-8.4-ubuntu-latest 96.87% <100.00%> (+<0.01%) ⬆️
unit-8.5-ubuntu-latest 96.87% <100.00%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

Comment thread src/Statements/SelectStatement.php Outdated
Comment thread tests/Builder/StatementTest.php Outdated
@williamdes

williamdes commented Jun 22, 2026

Copy link
Copy Markdown
Member

Thank you for this contribution!
if you used AI please make it add a Co author line.
Also I would like that this PR branch is based on 5.11.x so next version has your fix and not just 6.0

And finally please fix lint step

Misc::getAliases() built a table-alias map with
`$tables[$thisDb][$expr->alias] = $expr->table` for every FROM/JOIN
expression. When a table has no alias, `$expr->alias` is null, so this
used null as an array offset, which is deprecated as of PHP 8.5. The
null-keyed entry was never read back: the only consumer looks up
`$tables[$thisDb][$expr->table]`, whose offset is always a non-empty
string.

Skip expressions without an alias. getAliases() output is unchanged.
Removes the now-resolved PossiblyNullArrayOffset baseline entry and adds
a regression test.
@ardittirana ardittirana force-pushed the fix-getaliases-null-array-offset branch from 04242cf to 1514837 Compare June 22, 2026 13:41
@ardittirana ardittirana changed the base branch from master to 5.11.x June 22, 2026 13:41
@ardittirana

Copy link
Copy Markdown
Contributor Author

Thanks for the review @williamdes, and for the helpful pointers. I've updated the PR:

  • Rebased onto 5.11.x and changed the PR base accordingly, so the fix lands in the next 5.11 release and merges up to 6.0. On this branch the affected code lives in src/Utils/Misc.php (getAliases()), which is also the spot reported in #20312, so this covers that path too.
  • Explicit null check: the guard is now if (null === $expr->alias || $expr->alias === '').
  • Removed the noisy comments in both the source and the test — agreed they didn't add value.
  • The change keeps getAliases() output identical (the null-keyed entry was never read back; the only consumer indexes $tables[$thisDb][$expr->table]), and I removed the now-resolved PossiblyNullArrayOffset entry from the Psalm baseline.
  • A regression test is added to MiscTest::getAliasesProvider.

Full suite is green locally. Please let me know if you'd like anything else adjusted.

@williamdes williamdes added this to the 5.11.2 milestone Jun 26, 2026

@williamdes williamdes left a comment

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.

Thanks !

@williamdes williamdes merged commit 12287ea into phpmyadmin:5.11.x Jun 26, 2026
23 checks passed
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.

2 participants