Skip to content

Commit

Permalink
fix(minifier): don't use reserved words for mangled identifiers (#30)
Browse files Browse the repository at this point in the history
  • Loading branch information
CodyJasonBennett authored Feb 16, 2025
1 parent 43d13ad commit ba5f792
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 1 deletion.
8 changes: 7 additions & 1 deletion src/minifier.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { type Token, tokenize } from './tokenizer.js'
import { GLSL_KEYWORDS, WGSL_KEYWORDS } from './constants.js'

export type MangleMatcher = (token: Token, index: number, tokens: Token[]) => boolean

Expand All @@ -19,6 +20,9 @@ const isStorage = /* @__PURE__ */ RegExp.prototype.test.bind(
/^(binding|group|layout|uniform|in|out|attribute|varying)$/,
)

// Checks for WGSL-specific `fn foo(`, `var bar =`, `let baz =`, `const qux =`
const WGSL_REGEX = /\bfn\s+\w+\s*\(|\b(var|let|const)\s+\w+\s*[:=]/

const NEWLINE_REGEX = /\\\s+/gm
const DIRECTIVE_REGEX = /(^\s*#[^\\]*?)(\n|\/[\/\*])/gm

Expand All @@ -35,6 +39,8 @@ export function minify(
// Escape newlines after directives, skip comments
code = code.replace(DIRECTIVE_REGEX, '$1\\$2')

const KEYWORDS = WGSL_REGEX.test(code) ? WGSL_KEYWORDS : GLSL_KEYWORDS

const mangleCache = new Map()
const tokens: Token[] = tokenize(code).filter((token) => token.type !== 'whitespace' && token.type !== 'comment')

Expand Down Expand Up @@ -127,7 +133,7 @@ export function minify(
(tokens[i - 1]?.value === 'fn' && (tokens[i - 2]?.value === ')' || tokens[i - 3]?.value === '@'))
const cache = isExternal ? mangleMap : mangleCache

while (!renamed || cache.has(renamed)) {
while (!renamed || cache.has(renamed) || KEYWORDS.includes(renamed)) {
renamed = ''
mangleIndex++

Expand Down
4 changes: 4 additions & 0 deletions tests/__snapshots__/index.test.ts.snap
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`minify > avoids reserved words like as during mangle 1`] = `"var a=0;var b=0;var c=0;var d=0;var e=0;var f=0;var g=0;var h=0;var u8=0;var i=0;var j=0;var k=0;var l=0;var m=0;var n=0;var o=0;var u16=0;var p=0;var q=0;var r=0;var s=0;var t=0;var u=0;var v=0;var w=0;var x=0;var y=0;var az=0;var aa=0;var ab=0;var ac=0;var ad=0;var u32=0;var ae=0;var af=0;var ag=0;var ah=0;var ai=0;var aj=0;var ak=0;var al=0;var am=0;var an=0;var ao=0;var ap=0;var aq=0;var ar=0;var at=0;var au=0;var av=0;var aw=0;var ax=0;var ay=0;"`;

exports[`minify > avoids reserved words like as during mangle 2`] = `Map {}`;

exports[`minify > can mangle GLSL 1`] = `
"#version 300 es
precision mediump float;
Expand Down
7 changes: 7 additions & 0 deletions tests/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -183,4 +183,11 @@ describe('minify', () => {
expect(minify(shader, { mangle: true, mangleExternals: true, mangleMap })).toMatchSnapshot()
expect(mangleMap).toMatchSnapshot()
})

it('avoids reserved words like as during mangle', () => {
const mangleMap = new Map()
const shader = /* glsl */ `${Array.from({ length: 53 }, (_, i) => `var u${i} = 0;`).join('')}`
expect(minify(shader, { mangle: true, mangleExternals: true, mangleMap })).toMatchSnapshot()
expect(mangleMap).toMatchSnapshot()
})
})

0 comments on commit ba5f792

Please sign in to comment.