Skip to content

Commit d026a90

Browse files
spinnyspiwalspinnyspiwal
authored andcommitted
Added math.log10 & loadstring polyfill (for the NumbersToExpressions Integrity Fix to satisfy safety guardrails Non-LuaJIT clients, and fix 'random' obfuscation failures), also fixed Scientific notation causing a large amount of errors when once again, not using LuaJIT. Prometheus is once again Lua Client Agnostic.
1 parent b35fa0e commit d026a90

3 files changed

Lines changed: 69 additions & 2 deletions

File tree

src/prometheus.lua

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,17 @@ end) then
3939
end
4040
end
4141

42+
if not math.log10 then
43+
local ln10 = math.log(10);
44+
math.log10 = function(x)
45+
return math.log(x) / ln10;
46+
end
47+
end
48+
49+
if not loadstring then
50+
loadstring = load
51+
end
52+
4253
-- newproxy polyfill
4354
_G.newproxy = _G.newproxy or function(arg)
4455
if arg then

src/prometheus/steps/NumbersToExpressions.lua

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ local visitast = require("prometheus.visitast")
1414
local util = require("prometheus.util")
1515
local logger = require("logger")
1616
local AstKind = Ast.AstKind
17+
local SAFE_INT_LIMIT = jit and math.huge or 2^53
18+
local MAX_VAL = jit and math.huge or 2^54
1719

1820
local NumbersToExpressions = Step:extend()
1921
NumbersToExpressions.Description = "This Step Converts number Literals to Expressions"
@@ -37,6 +39,9 @@ NumbersToExpressions.SettingsDescriptor = {
3739
NumberRepresentationMutation = {
3840
type = "boolean",
3941
default = false,
42+
43+
-- NOTE: This alias is a legacy misspelling preservation.
44+
-- Please don't remove it.
4045
aliases = { "NumberRepresentationMutaton" },
4146
},
4247

@@ -92,7 +97,9 @@ function NumbersToExpressions:init(_)
9297
end,
9398

9499
function(val, depth) -- Modulo
100+
if val > MAX_VAL then return false end
95101
local lhs, rhs = generateModuloExpression(val)
102+
if lhs > SAFE_INT_LIMIT or rhs > SAFE_INT_LIMIT then return false end
96103
if tonumber(tostring(lhs)) % tonumber(tostring(rhs)) ~= val then
97104
return false
98105
end
@@ -153,7 +160,30 @@ function NumbersToExpressions:CreateNumberExpression(val, depth)
153160

154161
local exp = math.floor(math.log10(math.abs(val)))
155162
local mantissa = val / (10 ^ exp)
156-
return Ast.NumberExpression(string.format("%.15ge%d", mantissa, exp))
163+
164+
-- LuaJIT has full double precision support. Meaning we don't need aggressive safety harnesses for LuaJIT.
165+
if jit then
166+
return Ast.NumberExpression(string.format("%.15ge%d", mantissa, exp))
167+
end
168+
169+
local formatStr = string.format("%ge%+d", mantissa, exp)
170+
local concatStr = mantissa .. "e" .. (exp >= 0 and "+" or "") .. exp
171+
172+
local formatVal = loadstring("return " .. formatStr)
173+
local concatVal = loadstring("return " .. concatStr)
174+
175+
local formatResult = formatVal and formatVal()
176+
local concatResult = concatVal and concatVal()
177+
178+
local formatErr = formatResult and math.abs(formatResult - val) or math.huge
179+
local concatErr = concatResult and math.abs(concatResult - val) or math.huge
180+
181+
if formatErr > 0 and concatErr > 0 then
182+
return Ast.NumberExpression(val)
183+
end
184+
185+
local useFormat = formatErr <= concatErr
186+
return Ast.NumberExpression(useFormat and formatStr or concatStr)
157187
end
158188

159189
if format == "normal" then
@@ -185,4 +215,4 @@ function NumbersToExpressions:apply(ast)
185215
end)
186216
end
187217

188-
return NumbersToExpressions
218+
return NumbersToExpressions

tests/strings-integrity.lua

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
--============================================================
2+
-- Strings Integrity Test Suite
3+
-- Target: NumbersToExpressions Step
4+
-- Author: SpinnySpiwal
5+
-- Purpose: Prevent any further quality regressions from NumbersToExpressions.
6+
-- There was no actual bugs per se, but the bug was the use of Vanilla Lua instead of LuaJIT.
7+
-- This test ensures that the obfuscator stays client-agnostic & doesn't require a specific Lua version.
8+
--============================================================
9+
local integrity = {}
10+
for i = 0, 255 do integrity[i+1]=i end
11+
assert(#integrity == 256, "Failed to create integrity array! Reason: array length is not 256!")
12+
local array = {}
13+
14+
local function chararray(str)
15+
for i = 1, #str do
16+
array[i] = string.byte(str:sub(i, i))
17+
end
18+
return array
19+
end
20+
21+
local cArray = chararray("\0\1\2\3\4\5\6\7\8\9\10\11\12\13\14\15\16\17\18\19\20\21\22\23\24\25\26\27\28\29\30\31\32\33\34\35\36\37\38\39\40\41\42\43\44\45\46\47\48\49\50\51\52\53\54\55\56\57\58\59\60\61\62\63\64\65\66\67\68\69\70\71\72\73\74\75\76\77\78\79\80\81\82\83\84\85\86\87\88\89\90\91\92\93\94\95\96\97\98\99\100\101\102\103\104\105\106\107\108\109\110\111\112\113\114\115\116\117\118\119\120\121\122\123\124\125\126\127\128\129\130\131\132\133\134\135\136\137\138\139\140\141\142\143\144\145\146\147\148\149\150\151\152\153\154\155\156\157\158\159\160\161\162\163\164\165\166\167\168\169\170\171\172\173\174\175\176\177\178\179\180\181\182\183\184\185\186\187\188\189\190\191\192\193\194\195\196\197\198\199\200\201\202\203\204\205\206\207\208\209\210\211\212\213\214\215\216\217\218\219\220\221\222\223\224\225\226\227\228\229\230\231\232\233\234\235\236\237\238\239\240\241\242\243\244\245\246\247\248\249\250\251\252\253\254\255")
22+
for i = 1, #cArray do
23+
if cArray[i] ~= integrity[i] then
24+
error("Integrity check failed!")
25+
end
26+
end

0 commit comments

Comments
 (0)