fix(api): normalize LuaJSON null sentinels to nil in decoded payloads
KOReader's bundled LuaJSON (json.require) decodes JSON null into a
truthy sentinel function instead of nil. getMetadata responses for a
newly linked book with no server-side progress carry
"progress": null, so the `if not result.progress` guard passed,
indexing the sentinel crashed KOReader outright, and the book could
not be opened ("attempt to index local 'progress' (a function value)"
at the pull handler). "annotations": null would crash
applyServerAnnotations the same way.
Strip the sentinels recursively at the decode boundary in _request so
every call site sees plain nil and existing nil-checks behave as
written. Reproduced in the KOReader flatpak runtime:
json.decode('{"a": null}') yields type(data.a) == "function".
Found while testing a newly OPDS-downloaded book that had no server
progress yet; the crash took down the whole application, not just the
plugin.
This commit is contained in:
1 parent
75bf511bc1
commit
b466af09b0
1 file changed
+18
@@ -1,5 +1,18 @@
|
||||
local json = require("json")
|
||||
local json_util = require("json.util")
|
||||
|
||||
-- Recursively replace LuaJSON's truthy null-sentinel functions with nil
|
||||
-- (JSON null), so server payloads behave like normal Lua tables.
|
||||
local function strip_json_nulls(t)
|
||||
for k, v in pairs(t) do
|
||||
if type(v) == "function" then
|
||||
t[k] = nil
|
||||
elseif type(v) == "table" then
|
||||
strip_json_nulls(v)
|
||||
end
|
||||
end
|
||||
return t
|
||||
end
|
||||
local logger = require("logger")
|
||||
local ltn12 = require("ltn12")
|
||||
local socketutil = require("socketutil")
|
||||
@@ -86,6 +99,11 @@ function BookhoardAPI:_request(method, path, body, timeouts)
|
||||
if response_body and #response_body > 0 then
|
||||
local decode_ok, data = pcall(json.decode, response_body)
|
||||
if decode_ok and type(data) == "table" then
|
||||
-- LuaJSON decodes JSON null into a truthy sentinel FUNCTION,
|
||||
-- which defeats every `if not x.field` nil-check downstream
|
||||
-- (crash: "attempt to index local 'progress' (a function
|
||||
-- value)"). Normalize sentinels to nil at the boundary.
|
||||
strip_json_nulls(data)
|
||||
return true, data
|
||||
end
|
||||
return true, response_body
|
||||
|
||||
Reference in new issue
Block a user