Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions src/prometheus.lua
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,17 @@ end) then
end
end

if not math.log10 then
local ln10 = math.log(10);
math.log10 = function(x)
return math.log(x) / ln10;
end
end

if not loadstring then
loadstring = load
end

-- newproxy polyfill
_G.newproxy = _G.newproxy or function(arg)
if arg then
Expand Down
34 changes: 32 additions & 2 deletions src/prometheus/steps/NumbersToExpressions.lua
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ local visitast = require("prometheus.visitast")
local util = require("prometheus.util")
local logger = require("logger")
local AstKind = Ast.AstKind
local SAFE_INT_LIMIT = jit and math.huge or 2^53
local MAX_VAL = jit and math.huge or 2^54

local NumbersToExpressions = Step:extend()
NumbersToExpressions.Description = "This Step Converts number Literals to Expressions"
Expand All @@ -37,6 +39,9 @@ NumbersToExpressions.SettingsDescriptor = {
NumberRepresentationMutation = {
type = "boolean",
default = false,

-- NOTE: This alias is a legacy misspelling preservation.
-- Please don't remove it.
aliases = { "NumberRepresentationMutaton" },
},

Expand Down Expand Up @@ -92,7 +97,9 @@ function NumbersToExpressions:init(_)
end,

function(val, depth) -- Modulo
if val > MAX_VAL then return false end
local lhs, rhs = generateModuloExpression(val)
if lhs > SAFE_INT_LIMIT or rhs > SAFE_INT_LIMIT then return false end
if tonumber(tostring(lhs)) % tonumber(tostring(rhs)) ~= val then
return false
end
Expand Down Expand Up @@ -153,7 +160,30 @@ function NumbersToExpressions:CreateNumberExpression(val, depth)

local exp = math.floor(math.log10(math.abs(val)))
local mantissa = val / (10 ^ exp)
return Ast.NumberExpression(string.format("%.15ge%d", mantissa, exp))

-- LuaJIT has full double precision support. Meaning we don't need aggressive safety harnesses for LuaJIT.
if jit then
return Ast.NumberExpression(string.format("%.15ge%d", mantissa, exp))
end

local formatStr = string.format("%ge%+d", mantissa, exp)
local concatStr = mantissa .. "e" .. (exp >= 0 and "+" or "") .. exp

local formatVal = loadstring("return " .. formatStr)
local concatVal = loadstring("return " .. concatStr)

local formatResult = formatVal and formatVal()
local concatResult = concatVal and concatVal()

local formatErr = formatResult and math.abs(formatResult - val) or math.huge
local concatErr = concatResult and math.abs(concatResult - val) or math.huge

if formatErr > 0 and concatErr > 0 then
return Ast.NumberExpression(val)
end

local useFormat = formatErr <= concatErr
return Ast.NumberExpression(useFormat and formatStr or concatStr)
end

if format == "normal" then
Expand Down Expand Up @@ -185,4 +215,4 @@ function NumbersToExpressions:apply(ast)
end)
end

return NumbersToExpressions
return NumbersToExpressions
26 changes: 26 additions & 0 deletions tests/strings-integrity.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
--============================================================
-- Strings Integrity Test Suite
-- Target: NumbersToExpressions Step
-- Author: SpinnySpiwal
-- Purpose: Prevent any further quality regressions from NumbersToExpressions.
-- There was no actual bugs per se, but the bug was the use of Vanilla Lua instead of LuaJIT.
-- This test ensures that the obfuscator stays client-agnostic & doesn't require a specific Lua version.
--============================================================
local integrity = {}
for i = 0, 255 do integrity[i+1]=i end
assert(#integrity == 256, "Failed to create integrity array! Reason: array length is not 256!")
local array = {}

local function chararray(str)
for i = 1, #str do
array[i] = string.byte(str:sub(i, i))
end
return array
end

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")
for i = 1, #cArray do
if cArray[i] ~= integrity[i] then
error("Integrity check failed!")
end
end
Loading