Skip to content

NullPage: newNullPage() now returns a pooled singleton and isChanged() returns hasSets — surprising aliasing (a7884201 + 01d6cc00) #2244

@adrianbj

Description

@adrianbj

Short description of the issue

Commits a7884201 and 01d6cc00 together changed two NullPage invariants:

  1. newNullPage() now returns a pooled singleton by default (previously every call returned a fresh instance).
  2. isChanged() now returns $this->hasSets rather than always false.

Code that compared NullPages by identity ($a === $b) or relied on NullPage as an "always clean" sentinel can now observe surprising aliasing and a non-clean state.

Expected behavior

newNullPage() returns a fresh, never-changed NullPage on every call (the historical contract).

Actual behavior

wire/core/NullPage.php:73-78 + Pages::newNullPage():

  • Default behavior is to return the pooled singleton.
  • isChanged() returns true if set() has been called on the singleton — but the same singleton is then returned to other callers, leaking state.

Optional: Suggestion for a possible fix

Either:

  1. Revert the default to forceNew=true (always-fresh) and have specific callers opt into pooling via the existing forceNew=false argument.
  2. Document the new pooling contract prominently as a BC break and audit core call sites that mutate NullPage via set().

Setup/Environment

  • ProcessWire version: dev @ 15c749ed
  • Files: wire/core/NullPage.php:73-78, wire/core/Pages/Pages.php (newNullPage)
  • Introduced across commits a7884201, 01d6cc00

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions