Skip to content

[3.0] Recognise a gallery avatar as a file name, not a url - #9442

Open
albertlast wants to merge 1 commit into
SimpleMachines:release-3.0from
albertlast:3.0/avatar-prepackaged-persist
Open

[3.0] Recognise a gallery avatar as a file name, not a url#9442
albertlast wants to merge 1 commit into
SimpleMachines:release-3.0from
albertlast:3.0/avatar-prepackaged-persist

Conversation

@albertlast

Copy link
Copy Markdown
Collaborator

Description

An avatar picked out of the gallery is stored as a path relative to the avatars directory —
Oxygen/cards.png — not as a url. Avatar has no case for that, so it falls through to its
last resort, which pulls the path out of the url and looks for the file under the avatar
directories relative to the board directory.

That only lines up when the forum is installed under a path prefix. Two things go wrong
otherwise:

Every page is a fatal error. At the root of a domain there is no path to strip, and the
code reads it anyway:

preg_quote(Url::create(Config::$boardurl)->path, '~')

Url::$path is typed with no default and was never assigned, so:

Typed property SMF\Url::$path must not be accessed before initialization
  —  Sources/Avatar.php:539

One member with a gallery avatar takes down the board index, every topic they posted in,
the memberlist and their profile.

And the choice never sticks. Profile::setAvatarServerStored() puts the right value in
place — verified, new_data['avatar'] = 'Oxygen/cards.png' — but saving a member runs it
back through Avatar, and since that cannot resolve it, User::updateMemberData() writes
the column from whatever the object settled for instead. Set by hand, the avatar rendered
as default.png, and Avatar::$choice reported none, so the picker came back with
No avatar selected.

A string with no scheme is a file name. Saying so before the search starts lets it match on
attempt 2, where the prepackaged avatar directory is already handled, and the last-resort
url guessing is never reached.

Checked

http://localhost:8080 — a forum at the root of its domain.

Before, with smf_members.avatar = Oxygen/bug.png:

page
board index 500
their profile 500

After, saving each choice in turn through Profile → Forum Profile and re-reading the
profile:

chosen column rendered
gallery, nested (Oxygen/cookie.png) Oxygen/cookie.png …/avatars/Oxygen/cookie.png
gallery, top level (default.png) '' …/avatars/default.png
no avatar '' …/avatars/default.png
gravatar gravatar:// secure.gravatar.com/avatar/…
back to gallery (Oxygen/bug.png) Oxygen/bug.png …/avatars/Oxygen/bug.png

smf_log_errors stayed empty throughout. The top-level default.png storing as '' is
existing behaviour — User::updateMemberData() treats the default image as "no avatar".

This also settles the crash that #9440 guards against, by never reaching that branch for a
gallery avatar. #9440 is still worth having: it is the defensive fix for anything else that
gets that far with a pathless forum url.

Issues References (Fixes|Related|Closes)

Related #9440, #9441

An avatar picked out of the gallery is stored as a path relative to the
avatars directory: "Oxygen/cards.png", not a url. Avatar had no case for
that, so it fell through to the last resort, which pulls the path out of
the url and looks for the file under the avatar directories relative to
the board directory. That only lines up when the forum is installed
under a path prefix; at the root of a domain it reads
Url::create(Config::$boardurl)->path, which is a typed property that was
never assigned, and throws.

So a forum at the root of its domain was a fatal error on every page
showing a member with a gallery avatar - the board index included, by way
of the last-post line - and everywhere else the avatar came out as
default.png.

It also meant the choice never stuck. Profile::setAvatarServerStored()
puts the right value in place, but saving a member runs it back through
Avatar, and since that could not resolve it, the column was written with
whatever it had settled for instead.

A string with no scheme is a file name. Saying so before the search
starts lets it match on the second attempt, where the prepackaged avatar
directory is already handled.

Signed-off-by: Mathias Alberts <mathiaspapealbert@hotmail.com>
Signed-off-by: albertlast <mathiaspapealbert@hotmail.com>
@jdarwood007 jdarwood007 added this to the 3.0 Alpha 6 milestone Aug 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants