Skip to content

Add Lua compatibility profiles, strict LuaU syntax gating, and step/runtime hardening#1

Open
Copilot wants to merge 5 commits intomasterfrom
copilot/recommendations-for-improvements
Open

Add Lua compatibility profiles, strict LuaU syntax gating, and step/runtime hardening#1
Copilot wants to merge 5 commits intomasterfrom
copilot/recommendations-for-improvements

Conversation

Copy link
Copy Markdown

Copilot AI commented Apr 13, 2026

This PR addresses the current LuaU support gaps and decompiler-resilience concerns by tightening language-mode correctness and making profile-driven behavior explicit. It also reduces brittle Lua-version assumptions in transform steps and strengthens anti-tamper/entropy handling.

  • Language-mode correctness and strict feature gating

    • Fixed LuaU expression gating in parser logic (if(LuaVersion.LuaU) path now correctly uses parser/profile state).
    • Added explicit feature flags to parser behavior (continue, compound assignment, if-else expression, typed syntax).
    • Added clear, early parser errors for unsupported syntax per profile/version instead of ambiguous downstream failures.
  • Compatibility profiles and default alignment

    • Introduced profile model in pipeline:
      • Lua51 (default)
      • LuaU-safe
      • LuaU-typed
    • Aligned tokenizer/parser/unparser defaults to Lua51 and profile-driven configuration.
    • Added CLI profile selection support and preset profile metadata.
  • Step compatibility and Lua-version-safe snippet parsing

    • Added SupportedLuaVersions metadata and pipeline-side validation for steps.
    • Updated generated-code parsing in AntiTamper, ConstantArray, and EncryptStrings to use the active pipeline Lua version instead of hardcoded Lua51.
  • Security and anti-tamper hardening

    • Hardened RNG seed path when OpenSSL entropy is unavailable (mixed-entropy fallback path, non-fatal).
    • Added AntiTamper FailMode (error, return, loop) and randomized tamper detection message material to reduce static signatures.
  • LuaU-focused coverage and docs

    • Added LuaU feature test input and harness logic for LuaU output parsing checks.
    • Added doc/luau-feature-matrix.md to document supported LuaU features, profile behavior, and strict failure semantics.
    • Updated README/docs to surface compatibility profiles and feature matrix.
-- profile-driven pipeline config
local pipeline = Prometheus.Pipeline:fromConfig({
  CompatibilityProfile = "LuaU-safe",
  LuaVersion = "LuaU",
  Steps = { { Name = "Vmify", Settings = {} } }
})

@SkieAdmin
Copy link
Copy Markdown

Copilot did this shit, idk lol

@SkieAdmin SkieAdmin marked this pull request as ready for review April 13, 2026 10:45
Copilot AI review requested due to automatic review settings April 13, 2026 10:45
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces explicit compatibility profiles and profile-driven parser feature gating to improve Lua51/LuaU correctness, while also hardening parts of the pipeline runtime (step compatibility checks, helper-snippet parsing, RNG seeding) and adding LuaU-focused tests/docs.

Changes:

  • Added compatibility profile model (Lua51, LuaU-safe, LuaU-typed) and propagated profile feature flags into the parser/pipeline.
  • Hardened pipeline/steps by validating step Lua-version support and parsing generated helper snippets with the active pipeline Lua version.
  • Added LuaU feature tests and documentation (feature matrix + README updates).

Reviewed changes

Copilot reviewed 15 out of 15 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
tests/luau-features.lua Adds a LuaU-focused test case exercising continue and compound assignment.
tests.lua Adds LuaU test detection and a syntax-parse validation path for LuaU outputs.
src/prometheus/unparser.lua Aligns Unparser default Lua version to Lua51 (and initializes settings defensively).
src/prometheus/tokenizer.lua Aligns Tokenizer default Lua version to Lua51.
src/prometheus/steps/EncryptStrings.lua Parses generated helper code using the active pipeline Lua version.
src/prometheus/steps/ConstantArray.lua Parses generated helper snippets using the pipeline Lua version (stored per apply).
src/prometheus/steps/AntiTamper.lua Adds FailMode, randomizes tamper message, and parses snippet with pipeline Lua version.
src/prometheus/steps.lua Adds SupportedLuaVersions metadata for steps and refactors step module loading.
src/prometheus/pipeline.lua Introduces compatibility profiles + feature flags, step-version validation, and RNG entropy fallback.
src/prometheus/parser.lua Fixes LuaU expression gating bug, adds feature-flag-based syntax gating and clearer errors.
src/presets.lua Adds profile fields to presets and introduces LuaU preset variants.
src/cli.lua Adds --profile option and aligns --Lua51/--LuaU with default profiles.
readme.md Documents compatibility profiles and links to the LuaU feature matrix.
doc/README.md Links to local LuaU feature matrix documentation.
doc/luau-feature-matrix.md Adds a profile/feature matrix describing supported LuaU constructs and failure behavior.
Comments suppressed due to low confidence (2)

src/prometheus/pipeline.lua:131

  • Pipeline:fromConfig always passes a concrete LuaVersion (defaulting to Pipeline.DefaultSettings.LuaVersion) even when a CompatibilityProfile is provided. This prevents the profile from selecting its intended Lua version and can produce an inconsistent pipeline (e.g., Lua51 tokenizer/parser conventions with LuaU feature flags). Consider only setting LuaVersion when explicitly provided in config, or resolving LuaVersion from the selected profile when config.LuaVersion is nil.
function Pipeline:fromConfig(config)
	config = config or {};
	local pipeline = Pipeline:new({
		LuaVersion = config.LuaVersion or Pipeline.DefaultSettings.LuaVersion;
		CompatibilityProfile = config.CompatibilityProfile or Pipeline.DefaultSettings.CompatibilityProfile;
		PrettyPrint = config.PrettyPrint or false;
		VarNamePrefix = config.VarNamePrefix or "";
		Seed = config.Seed or 0;
	});

src/prometheus/pipeline.lua:194

  • Pipeline:getLuaVersion() returns self.luaVersion, but the pipeline stores the active version as self.LuaVersion (and setLuaVersion updates self.LuaVersion). This currently returns nil/stale values; return self.LuaVersion instead.
	self.LuaVersion = luaVersion;
end

function Pipeline:getLuaVersion()
	return self.luaVersion;

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +73 to +77
local profileName = settings.CompatibilityProfile or settings.compatibilityProfile or Pipeline.DefaultSettings.CompatibilityProfile;
local profile = CompatibilityProfiles[profileName];
if profile then
return profileName, profile;
end
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

resolveCompatibilityProfile silently returns nil for unknown profile names, which makes typos/config mistakes fall back to defaults without a clear error. Consider raising a parser/config error (similar to unknown LuaVersion) when settings.CompatibilityProfile is set but not found in CompatibilityProfiles.

Suggested change
local profileName = settings.CompatibilityProfile or settings.compatibilityProfile or Pipeline.DefaultSettings.CompatibilityProfile;
local profile = CompatibilityProfiles[profileName];
if profile then
return profileName, profile;
end
local explicitProfileName = settings.CompatibilityProfile or settings.compatibilityProfile;
local profileName = explicitProfileName or Pipeline.DefaultSettings.CompatibilityProfile;
local profile = CompatibilityProfiles[profileName];
if profile then
return profileName, profile;
end
if explicitProfileName then
logger:error("The Compatibility Profile \"" .. explicitProfileName
.. "\" is not recognized! Please use one of the following: \"" .. table.concat(util.keys(CompatibilityProfiles), "\",\"") .. "\"");
end

Copilot uses AI. Check for mistakes.
FeatureFlags = self.FeatureFlags;
});
self.unparser = Unparser:new({
luaVersion = luaVersion;
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pipeline:setLuaVersion re-creates the Unparser with { luaVersion = luaVersion }, but Unparser:new reads settings.LuaVersion (capital V). This means setLuaVersion can leave the Unparser using the default version instead of the requested one. Pass LuaVersion = luaVersion (or update Unparser:new to accept settings.luaVersion too) to keep Parser/Unparser consistent.

Suggested change
luaVersion = luaVersion;
LuaVersion = luaVersion;

Copilot uses AI. Check for mistakes.
function Unparser:new(settings)
local luaVersion = settings.LuaVersion or LuaVersion.LuaU;
settings = settings or {};
local luaVersion = settings.LuaVersion or LuaVersion.Lua51;
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unparser:new only checks settings.LuaVersion, but other constructors (Tokenizer/Parser) accept both luaVersion and LuaVersion, and Pipeline:setLuaVersion currently passes luaVersion. Consider also reading settings.luaVersion here to avoid version mismatches and keep the API consistent.

Suggested change
local luaVersion = settings.LuaVersion or LuaVersion.Lua51;
local luaVersion = settings.luaVersion or settings.LuaVersion or LuaVersion.Lua51;

Copilot uses AI. Check for mistakes.
fc = fc + 1;
if isLuaUTest then
local ok, err = pcall(function()
Parser:new({ LuaVersion = Enums.LuaVersion.LuaU }):parse(obfuscated)
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LuaU tests only validate syntax with Parser:new({ LuaVersion = Enums.LuaVersion.LuaU }), which ignores the active compatibility profile feature flags. This can miss cases where the pipeline outputs LuaU syntax that is disallowed by the selected profile (e.g., if/else expressions if that flag is disabled). Consider passing the same FeatureFlags used by the pipeline/profile into this Parser instance.

Suggested change
Parser:new({ LuaVersion = Enums.LuaVersion.LuaU }):parse(obfuscated)
local parserOptions = {
LuaVersion = Enums.LuaVersion.LuaU,
FeatureFlags = pipeline.FeatureFlags or runPreset.FeatureFlags,
}
Parser:new(parserOptions):parse(obfuscated)

Copilot uses AI. Check for mistakes.
Comment on lines 1014 to 1016
-- IfElse
if(LuaVersion.LuaU) then
if(self.featureFlags.AllowIfElseExpression) then
if(consume(self, TokenKind.Keyword, "if")) then
Copy link

Copilot AI Apr 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When AllowIfElseExpression is false and the input contains an if ... then ... else ... expression, the parser falls through to the generic "Unexpected Token" error. If the goal is strict feature gating with clear errors per profile, consider explicitly detecting if here when the flag is disabled and raising a targeted error message.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants