Skip to content

[2.x] Sourcemap library emits null-array-offset deprecations on PHP 8.5 when compiling assets #4894

Description

@imorland

Summary

Compiling frontend assets on PHP 8.5 emits Using null as an array offset is deprecated, use an empty string instead from the sourcemap library, once per mapped position. On a forum with debug and display_errors on, that is hundreds of lines per request.

PHP Deprecated:  Using null as an array offset is deprecated, use an empty string instead in /var/www/vendor/axy/sourcemap/src/parsing/Line.php on line 495
PHP Deprecated:  Using null as an array offset is deprecated, use an empty string instead in /var/www/vendor/axy/sourcemap/src/parsing/Line.php on line 495
...

Originally reported against sycho/sourcemap at Line.php lines 499 and 496. Since #4895 we depend on upstream axy/sourcemap, where the same code sits at 495 and 496.

Cause

Line::concat() guards the array access with the operands the wrong way round:

if ((isset($mSources[$fi])) && ($fi !== null)) {
    $source->fileIndex = $mSources[$fi];
}
if ((isset($mNames[$ni])) && ($ni !== null)) {
    $source->nameIndex = $mNames[$ni];
}

isset($mSources[$fi]) evaluates the offset before $fi !== null is ever reached, so the null check is unreachable and the null offset is what PHP 8.5 warns about. $fi and $ni are null whenever a position has no source file or name, which is common.

Swapping the operands fixes it, and cannot change behaviour: isset() on a null offset was already false.

if (($fi !== null) && (isset($mSources[$fi]))) {

Verified on PHP 8.5.9 — the notice is emitted before, silent after, with byte-identical mappings output through JsCompiler's own call path. PHP 8.3 and 8.4 do not warn.

In practice it is the first guard that fires: a position without a source file is routine, whereas one without a name is rarer, which is why the logs are dominated by a single line number. Both are wrong and both want fixing.

Where it needs fixing

Not in Flarum — the library. flarum/core only calls new SourceMap() and ->concat() from JsCompiler.

This was never specific to the sycho/sourcemap fork: upstream axy/sourcemap 1.1.0 has the identical guard, so moving to it did not resolve the deprecation on its own, as expected.

Running upstream's own test suite on PHP 8.5 shows Line.php is the only deprecation in its source; the others it reports come from its dependencies, axy/errors and axy/codecs-base64vlq, which are separate repositories and separate reports.

Why a maintained package still has it

Upstream's CI does test PHP 8.1 through 8.5, added in the 1.1.0 release. But its phpunit.xml.dist sets no failOnDeprecation, and PHPUnit reports deprecations without failing on them — so the 8.5 job passes while carrying them. Nothing has surfaced it to the maintainer.

Plan

  1. Move off the unmaintained fork to upstream axy/sourcemap — done in [2.x] chore: use the upstream sourcemap package #4895. Worth doing on its own merits, and a prerequisite for a fix reaching us through a release rather than a patch we carry.
  2. Report and fix upstream at axypro/sourcemap.

This issue tracks the deprecation until an upstream release carries the fix.

Environment

  • PHP 8.5
  • Flarum 2.x

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions