1
0
forked from osmarks/potatOS

Fix accreted software horrors

- Internal CC changes break hacky stacktrace thing
- CraftOS-PC refuses to boot it due to some bizarre issue with ipairs
- Superglobals backend (JSON storage service) replaced with new RSAPI service due to downtime
- Internal CC changes break incomplete FS overlay mechanism (implement full version)
- Chuck Norris joke API service broke (replace with another)
This commit is contained in:
2023-08-13 00:52:16 +01:00
parent 8f15e7e6ef
commit fd2ae8cbb3
10 changed files with 616 additions and 304 deletions

View File

@@ -66,7 +66,8 @@ local function xpcall_with(fn, ...)
local res = table.pack(_xpcall(function() return fn(unpack(args)) end, traceback)) if not res[1] then trace = traceback("stack_trace.lua:1:") end
local ok, err = res[1], res[2]
if not ok and err ~= nil then
-- PS#EAB415D8: CC now uses error sentinel things in some places; we do not want to make those strings
if not ok and err ~= nil and type(err) == "string" then
trace = trim_traceback(err, trace)
-- Find the position where the stack traceback actually starts

View File

@@ -138,18 +138,6 @@ local function combine(segs)
end
return out
end
-- magic from http://lua-users.org/wiki/SplitJoin
-- split string into lines
local function lines(str)
local t = {}
local function helper(line)
table.insert(t, line)
return ""
end
helper((str:gsub("(.-)\r?\n", helper)))
return t
end
-- Fetch the contents of URL "u"
local function fetch(u)
@@ -160,12 +148,28 @@ local function fetch(u)
end
-- Make a read handle for a string
-- PS#8FE487EF: Incompletely implemented handle behaviour lead to strange bugs on recent CC
local function make_handle(text)
local lines = lines(text)
local h = {line = 0}
local h = {}
local cursor = 1
function h.close() end
function h.readLine() h.line = h.line + 1 return lines[h.line] end
function h.readAll() return text end
function h.readLine(with_trailing)
if cursor >= text:len() then return nil end
local lt_start, lt_end = text:find("\r?\n", cursor)
lt_start = lt_start or (text:len() + 1)
lt_end = lt_end or (text:len() + 1)
local seg = text:sub(cursor, with_trailing and lt_end or (lt_start - 1))
ccemux.echo(("%d %d %d %q %q"):format(cursor, lt_start, lt_end, text, text:sub(cursor)))
cursor = lt_end + 1
return seg
end
function h.read(count)
local count = count or 1
local seg = text:sub(cursor, cursor + count - 1)
cursor = cursor + count
return seg:len() ~= 0 and seg or nil
end
function h.readAll() local seg = text:sub(cursor) cursor = text:len() return seg:len() ~= 0 and seg or nil end
return h
end

View File

@@ -842,10 +842,11 @@ local function gen_uuid()
return table.concat(out)
end
-- PS#44BE67B6: ipairs somehow causing issues on CraftOS-PC
local function hexize(tbl)
local out = {}
for k, v in ipairs(tbl) do
out[k] = ("%02x"):format(v)
for k = 1, #tbl do
out[k] = string.format("%02x", tbl[k])
end
return table.concat(out)
end
@@ -1580,6 +1581,7 @@ end
return function(...)
local command = table.concat({...}, " ")
add_log("command line is %q", command)
-- Removes whitespace. I don't actually know what uses this either.
local function strip_whitespace(text)
@@ -1607,7 +1609,8 @@ return function(...)
if config.get "romReadOnly" ~= false then pcall(config.set, "romReadOnly", false) end -- TODO: do something COOL with this.
end
if not polychoron or not fs.exists "potatobios.lua" or not fs.exists "autorun.lua" then -- Polychoron not installed, so PotatOS Tau isn't.
if not polychoron or not fs.exists "potatobios.lua" or not fs.exists "autorun.lua" then -- Polychoron not installed, so PotatOS isn't.
add_log "running installation"
install(true)
else
process.spawn(function() -- run update task in kindofbackground process

View File

@@ -26,6 +26,10 @@ function _G.error(...)
if math.random(1, 100) == 5 then
real_error("vm:error: java.lang.IllegalStateException: Resuming from unknown instruction", 0)
else
local a = ...
if ccemux then
pcall(function() ccemux.echo("error: " .. textutils.serialise(a) .. "\n" .. debug.traceback()) end)
end
real_error(...)
end
end
@@ -1190,8 +1194,9 @@ function potatOS.restart_UI()
end
-- Simple HTTP.get wrapper
function fetch(u)
local h,e = http.get(u)
function fetch(u, ...)
if not http then error "No HTTP access" end
local h,e = http.get(u, ...)
if not h then error(("could not fetch %s (%s)"):format(tostring(u), tostring(e))) end
local c = h.readAll()
h.close()
@@ -1212,46 +1217,37 @@ JSONBin (https://jsonbin.org/) recently adjusted their policies in a way which b
Fix for PS#18819189
MyJSON broke *too* somehow (I have really bad luck with these things!) so move from https://api.myjson.com/bins/150r92 to "JSONBin".
Fix for PS#8C4CB942
The other JSONBin thing broke too so just implement it in RSAPI
]]
local bin_URL = "https://jsonbase.com/potatOS/superglobals"
local bin_URL = "https://r.osmarks.net/superglobals/"
local bin = {}
local localbin = {}
function bin.dump()
local fetch_result = {}
parallel.waitForAny(function()
fetch_result = json.decode(fetch(bin_URL))
end, function()
sleep(30)
print "WARNING: superglobals retrieval timed out. Reporting incident."
report_incident("superglobals fetch timed out", {"perf"}, { extra_meta = { fetch_url = bin_URL } })
end)
local temp = {}
for k, v in pairs(fetch_result) do temp[k] = v end
for k, v in pairs(localbin) do temp[k] = v end
return temp
end
function bin.get(k)
potatOS.add_log("asked to fetch %s", k)
return localbin[k] or bin.dump()[k]
if localbin[k] then
return localbin[k]
else
local ok, err = pcall(function()
local r = fetch(bin_URL .. textutils.urlEncode(tostring(k)), nil, true)
local ok, err = pcall(json.decode, r)
if not ok then return r end
return err
end)
if not ok then potatOS.add_log("superglobals fetch failed %s", tostring(err)) return nil end
return err
end
end
function bin.set(k, v)
local ok, err = pcall(function()
local b = bin.dump()
b[k] = v
local h, err = http.post {
url = "https://jsonbase.com/potatOS/superglobals",
method = "PUT",
body = json.encode(b),
headers = {
["content-type"] = "application/json"
}
}
local h, err = http.post(bin_URL .. textutils.urlEncode(tostring(k)), json.encode(v), nil, true)
if not h then error(err) end
end)
if not ok then localbin[k] = v end
if not ok then localbin[k] = v potatOS.add_log("superglobals set failed %s", tostring(err)) end
end
local bin_mt = {
@@ -1450,11 +1446,49 @@ function num_funcs.isInf(x) return math.abs(x) == math.huge end
_G.potatOS.bin = bin
function potatOS.fasthash(str)
local h = 5381
for c in str:gmatch "." do
h = (bit.blshift(h, 5) + h) + string.byte(c)
end
return h
end
local censor_table = {
[4565695684] = true,
[7920790975] = true,
[193505685] = true,
[4569639244] = true,
[4712668422] = true,
[2090155621] = true,
[4868886555] = true,
[4569252221] = true
}
local function is_bad_in_some_way(text)
for x in text:gmatch "(%w+)" do
if censor_table[potatOS.fasthash(x)] then
return true
end
end
return false
end
local function timeout(fn, time)
local res = {}
parallel.waitForAny(function() res = {fn()} end, function() sleep(time) end)
return table.unpack(res)
end
-- Connect to random text generation APIs. Not very reliable.
-- PS#BB87FCE2: Previous API broke, swap it out
function _G.potatOS.chuck_norris()
local resp = fetch "http://api.icndb.com/jokes/random?exclude=[explicit]"
local text = json.decode(resp).value.joke:gsub(""", "'")
return text
--local resp = fetch "http://api.icndb.com/jokes/random?exclude=[explicit]"
while true do
local resp = fetch("https://api.api-ninjas.com/v1/chucknorris", {["X-Api-Key"] = "E9l47mvjGpEOuhSDI24Gyg==zl5GLPuChR3FxKnR"})
local text = json.decode(resp).joke:gsub("[\127-\255]+", "'")
if not is_bad_in_some_way(text) and text:match ".$" == "." then return text end
end
end
-- Remove paragraph tags from stuff.
@@ -1693,7 +1727,7 @@ if potatOS.hidden ~= true then
local v = "PotatOS Hypercycle"
if potatOS.build then v = v .. " " .. potatOS.build end
if potatOS.version then v = v .. " " .. potatOS.version() end
local ok, err = pcall(randpick(stuff))
local ok, err = timeout(function() return pcall(randpick(stuff)) end, 0.7)
if ok then v = v .. "\n" .. err else
potatOS.add_log("motd fetch failed: %s", err)
v = v .. " [error fetching MOTD]"

View File

@@ -60,7 +60,7 @@ local m_ldexp = math.ldexp or function (x, exp) return x * 2.0 ^ exp; end;
local m_type = math.type or function (n) return n % 1 == 0 and n <= maxint and n >= minint and "integer" or "float" end;
local s_pack = string.pack or softreq("struct", "pack");
local s_unpack = string.unpack or softreq("struct", "unpack");
local b_rshift = softreq("bit32", "rshift") or softreq("bit", "rshift") or
local b_rshift = softreq("bit32", "rshift") or softreq("bit", "rshift") or (bit or {}).brshift or
dostring "return function(a,b) return a >> b end" or
function (a, b) return m_max(0, m_floor(a / (2 ^ b))); end;