luci-base: don't crash in String.format() on an undefined argument#8745
luci-base: don't crash in String.format() on an undefined argument#8745Cris7015 wants to merge 1 commit into
Conversation
A `%<n>m` conversion stores its divisor in the min-length slot, but when the argument was undefined the `if (param !== undefined)` block was skipped, so the divisor was never cleared while `subst` stayed undefined and the trailing `subst.toString()` in the padding loop threw. Use an empty substitution for an undefined argument and preserve the parsed field width, so values such as `'%10s'.format(undefined)` render as padding plus an empty string (ten spaces). `%m` stays special: it reuses the min-length slot as the metric divisor, not a field width, so clear it for undefined `%m` conversions just like the defined-argument path does, to avoid padding the empty value out to ~1024 characters. Also move the pad initialization ahead of the `param !== undefined` check so the common padding block has a valid pad character for undefined arguments too. As a side effect a plain `%s`/`%d` on an undefined argument now yields an empty string instead of the literal "undefined". Signed-off-by: Cristian Papa <pcristian292@gmail.com>
|
Worth calling out why this specifically threw instead of just producing bad output: subst/pad are declared once with |
|
Good point, thanks. You're right that the failure mode is broader than just the reported The intent of the patch is to reset the undefined-argument path in general by assigning an empty substitution, while still keeping |
Pull request details
Supersedes #8727. GitHub no longer allows reopening that PR after its source
branch was recreated, so this is the replacement PR with the corrected follow-up
from the review discussion there.
Description
The status Overview "Ports" widget (
view/status/include/29_ports.js) cancrash with
TypeError: Cannot read properties of undefined (reading 'toString')when a port's netdev reports no statistics. In that case
stats.rx_bytesandsimilar values are
undefined, and the widget formats them through:This aborts the entire Overview render.
Root cause:
String.prototype.format()runs its conversion switch only when theargument is defined (
if (param !== undefined)). For%m, the parsedpMinLengthslot is used as the metric divisor (%1024m), not as a fieldwidth, and the
%mswitch case clears it afterwards. With an undefined argumentthe switch is skipped, so
pMinLengthstays set whilesubststays undefined;the common padding block then calls
subst.toString()and throws.Fix undefined arguments by using an empty substitution. Preserve the parsed
field width for normal conversions, so e.g.
'%10s'.format(undefined)rendersten spaces as padding plus an empty string. Keep
%mspecial by clearingpMinLengthfor undefined%mconversions too, since that slot is the metricdivisor rather than a field width. Also move pad initialization before the
undefined-argument check so the common padding block has a valid pad character
in both paths.
Tested on
OpenWrt version: OpenWrt SNAPSHOT r34203 (target
econet/en751221, EcoNetEN751221) - TP-Link Archer XR500v
LuCI version: master
26.151.60149~1bffbf4Web browser(s): Chromium (used to capture the console stack trace)
Before: the Overview throws
Cannot read properties of undefined (reading 'toString')and renders nothing.After: the Ports panel renders normally, and formatter checks behave as expected:
Maintainer
@jow-
Checklist
fix-string-format-undefined-crash).Signed-off-by: Cristian Papa <pcristian292@gmail.com>row.<package name>: titlefirst-line subject (luci-base: ...).PKG_VERSION: N/A -luci-basehas noPKG_VERSION; it is versioned vialuci.mk/git.