securecallfunction, because modern libraries upvalue it at load time
The stitched map never said which zone you were looking at — from about zoom 3.5 to 10
there is no zone name anywhere on screen, which is the band a player pans around in.
Wiring up a port file that draws them took the addon corpus's "survived a UI probe" column
from 86/87 to 85/87, and the failure was not in the new file:
OpenMapClassic/Libs/CallbackHandler-1.0/CallbackHandler-1.0.lua:19:
attempt to call upvalue `securecallfunction' (a nil value)
Ace3's modern `CallbackHandler` takes `local securecallfunction = securecallfunction` on
its line 10 and calls it for **every handler of every event**, so the first callback any
addon shipping a post-2022 Ace fires raises. Nothing had fired one before, because
OpenMap's whole callback surface was dead for an unrelated reason until tonight.
1.12 has no taint, so there is nothing here to make secure — but the half of the contract
that is not about taint is the half library code leans on: it is a **protected** call, so
one raising handler does not stop the registry walking the rest. `securecallfunction`,
`securecall` (which also takes a global's name), `issecure` and `forceinsecure` go beside
`seterrorhandler` in `stdlib.rs`, with failures reaching `geterrorhandler()` exactly as the
reference's own secure dispatch does, so an addon bug still lands in the log rather than
being swallowed. Back to 86/87.
`the_rest_of_the_bare_globals` asserted these ABSENT, on the reasoning that the restricted
-execution system has no 1.12 counterpart and nothing here implements it. That was half
right; the half it missed is above, so the assertion is inverted with the measurement
written beside it — the same shape `hooksecurefunc` already has one line below.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SgstFWtn1RxEJ5kVrpgYwn
This commit is contained in:
@@ -4091,3 +4091,68 @@ Quality was checked rather than assumed: four THICKOUTLINE rows at the ladder's
|
||||
(0.889× minify, 1.118× magnify), same scene, both binaries. A control band with no rig text is
|
||||
**pixel-identical**, the tight bounding boxes of the 72 px and 90 px rows are identical to the
|
||||
pixel, and the text bands differ by 4.6–6.0% RMSE — edge antialiasing, invisible at 1:1.
|
||||
|
||||
## The stitched map never said which zone you were looking at
|
||||
|
||||
Blizzard's map writes the zone's name in the window chrome, because the window only ever shows one
|
||||
map. The stitched map is a continuous canvas with no "current map" to name, and measured over a
|
||||
capture sweep at zoom 1, 2, 3, 4, 5, 6, 10, 20 and 40, the only lettering on screen is what the art
|
||||
itself paints: the world sheet's `KALIMDOR` / `EASTERN KINGDOMS`, off the window's edge by zoom 3;
|
||||
each continent sheet's painting of **its own** name (this client's continent art paints no zone
|
||||
names at all — 1.12's `WorldMapContinent` sheets are coloured zone blobs and a title); and each
|
||||
zone sheet's sub-area names, `MENETHIL HARBOR`, `DUN ALGAZ`, which name a place inside a zone and
|
||||
never the zone. **From about zoom 3.5 to about zoom 10 there is no zone name anywhere on screen**,
|
||||
and that is the whole band a player pans around in.
|
||||
|
||||
Upstream fills this with `ns.MapLabels` and `Stitch.lua`'s `Letter()`; neither is usable here.
|
||||
`Data/Labels.lua` is empty in this fork because the positions were hand-placed against hand-cleaned
|
||||
art this client does not have, and `Letter()` builds one FontString per glyph plus an eight-tap
|
||||
halo ring per glyph — its own comment admits every one is moved on each frame of a pan and redrawn
|
||||
on each frame of a zoom, which is the glyph-sheet defect two sections up, by construction.
|
||||
|
||||
`Map/ZoneNames.lua` is one plain outlined FontString per zone instead. Three things make it cheap:
|
||||
|
||||
- **It hangs off the view, not the canvas.** The holder sits on `WorldMapFrame.ScrollContainer`,
|
||||
whose effective scale measured **1.0000 at every zoom** while the canvas measured 3.5261 at zoom
|
||||
5. A font height in view units is therefore a fixed device ppem, and `(face, glyph, ppem,
|
||||
outline)` keys one cell set for the whole session. Measured: **size 14 at every zoom in the
|
||||
sweep**, and zero `glyph sheet full` lines. It is the same move `MapCanvas.lua` already makes
|
||||
with `WorldMapFrameAreaFrame`.
|
||||
- **Positions still ride the canvas**, anchored to `WorldMapButton` with the `button / holder`
|
||||
scale factor `Map/StockArrow.lua` documents, so a pan is carried by the layout for free and only
|
||||
a zoom needs the callback.
|
||||
- **Two zoom bands, both read off the sweep.** In at `{ 3.4, 5.0 }`, a little ahead of
|
||||
`MUTE_FADE = { 4, 7 }` so the name is already there when the art stops helping; out at
|
||||
`{ 10, 16 }`, where the zone sheet's own lettering has taken over (`MENETHIL HARBOR` is fully
|
||||
readable at zoom 10 and mush at 5). A per-zone band in the style of `CITY_FADE` was tried and
|
||||
rejected: The Barrens fills the view at zoom 4.4, so its name would fade out before it finished
|
||||
fading in, and Moonglade fills it at 19.3 and would hang on past zoom 40.
|
||||
|
||||
The label is placed at the zone's rect centre **clamped into the part of that rect which is on
|
||||
screen**, inset by half the measured string. Pinning to the raw centre has two failures a player
|
||||
meets at ordinary zooms: a zone whose centre is off screen gets no name at all — between zoom 8 and
|
||||
10 that can be the very zone being looked at — and a centre near the canvas edge gets the word
|
||||
sliced, because the view clips its children. Measured at zoom 9 over Dun Morogh: **2 labels before
|
||||
the clamp, 6 after**, none sliced.
|
||||
|
||||
Cities are excluded (that is `Stitch.lua`'s own `S.stats.cities`), the whole thing is one
|
||||
`zoneNames` toggle, and with it off the shot is byte-identical to one taken with the file absent.
|
||||
Honest remainders: a name can overlap the sheet's own lettering (`DUN MOROGH` over `KHARANOS` at
|
||||
zoom 13, at 50% alpha), and during an easing zoom a label lags radially by a frame or two because
|
||||
the view callback is throttled to 0.15 s — pans are exact.
|
||||
|
||||
### `securecallfunction`, and why an empty taint system still needs one
|
||||
|
||||
Wiring that file up took the corpus's "survived a UI probe" column from 86/87 to **85/87**, and the
|
||||
failure was not in it: `OpenMapClassic/Libs/CallbackHandler-1.0/CallbackHandler-1.0.lua:19`,
|
||||
`attempt to call upvalue 'securecallfunction' (a nil value)`. Ace3's modern `CallbackHandler`
|
||||
upvalues that global on its line 10 and calls it for **every handler of every event**, so the first
|
||||
callback any addon shipping a post-2022 Ace fires raises. It had simply never fired before — the
|
||||
callbacks were dead for the other reason, two sections up.
|
||||
|
||||
1.12 has no taint, so there is nothing here to make secure. But the half of the contract that is
|
||||
not about taint is the half library code leans on: it is a **protected** call, so one handler
|
||||
raising does not stop the registry walking the rest. `securecallfunction`, `securecall` (which also
|
||||
takes a global's name), `issecure` and `forceinsecure` now live beside `seterrorhandler` in
|
||||
`stdlib.rs`, with failures going to `geterrorhandler()` exactly as the reference's own secure
|
||||
dispatch does — so an addon bug still reaches the log rather than being swallowed. Back to 86/87.
|
||||
|
||||
Reference in New Issue
Block a user