Skip to content

Commit

Permalink
refactor: use wasm for regex validation
Browse files Browse the repository at this point in the history
  • Loading branch information
javiersuweijie committed Oct 24, 2024
1 parent b04c67b commit 10b071d
Show file tree
Hide file tree
Showing 5 changed files with 164 additions and 59 deletions.
1 change: 1 addition & 0 deletions packages/app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"@zk-email/circuits": "6.1.1",
"@zk-email/helpers": "6.1.1",
"@zk-email/zk-email-sdk": "^1.0.5",
"@zk-email/relayer-utils": "^0.4.2",
"archiver": "^7.0.1",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.1",
Expand Down
61 changes: 2 additions & 59 deletions packages/app/src/app/submit/email/action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { z } from 'zod';
import { formSchema } from '../form';
import { generateCodeLibrary } from '@/lib/code-gen/gen';
import { verifyDKIMSignature } from "@zk-email/helpers/dist/dkim";
import { extractMatches, extractMatchesWasm, Values } from '@/lib/regex';

export interface ProcessEmailResult {
error: boolean,
Expand Down Expand Up @@ -73,7 +74,7 @@ export async function processEmail(values: z.infer<typeof formSchema>, email: st
}

// Apply regex
const matches = extractMatches(headerString, bodyString, values.parameters.values as Values[]);
const matches = await extractMatchesWasm(headerString, bodyString, values.parameters.values as Values[]);

const parameters = {
...values.parameters,
Expand All @@ -94,62 +95,4 @@ export async function processEmail(values: z.infer<typeof formSchema>, email: st
parameters: res,
matches,
}
}

interface Values {
name: string,
location: "header" | "body",
parts: {
regex_def: string,
is_public: boolean,
}[],
}

function extractMatches(headerString: string, bodyString: string | undefined, values: Values[]) {
const regexes = values.map((v: any) => {
let publicGroups: number[] = [];
let index = 1;
const regex = v.parts.reduce((acc: any, part: any) => {
if (part.regex_def.match(/\([^\)]+/)) index++;
if (part.is_public) {
publicGroups.push(index);
index++;
return acc + "(" + part.regex_def + ")"
}
return acc + part.regex_def
}, "");
return {
regex,
publicGroups,
name: v.name,
location: v.location,
}
})

let matches = []

for (const regex of regexes) {
if (regex.location == "body" && bodyString) {
const match = bodyString.match(regex.regex)
if (match) {
for (const group of regex.publicGroups) {
matches.push({
name: regex.name,
match: match[group],
})
}
}
} else {
const match = headerString.match(regex.regex)
if (match) {
for (const group of regex.publicGroups) {
matches.push({
name: regex.name,
match: match[group],
})
}
}
}
}
return matches;
}
103 changes: 103 additions & 0 deletions packages/app/src/lib/regex.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import initWasm, { extractSubstr, extractSubstrIdxes } from "@zk-email/relayer-utils";
import fs from "fs";

let wasmLoaded: Promise<boolean>;
const code = fs.readFileSync("node_modules/@zk-email/relayer-utils/relayer_utils_bg.wasm");
wasmLoaded = initWasm({ module_or_path: code }).then(() => {
return true;
})

export interface Values {
name: string,
location: "header" | "body",
parts: {
regex_def: string,
is_public: boolean,
}[],
}

export function extractMatches(headerString: string, bodyString: string | undefined, values: Values[]) {
const regexes = values.map((v: any) => {
let publicGroups: number[] = [];
let index = 1;
const regex = v.parts.reduce((acc: any, part: any) => {
const regexWithoutGroup = part.regex_def.replace("(", "(?:")
if (part.is_public) {
publicGroups.push(index);
index++;
return acc + "(" + regexWithoutGroup + ")"
}
return acc + regexWithoutGroup
}, "");
return {
regex,
publicGroups,
name: v.name,
location: v.location,
}
})

let matches = []

for (const regex of regexes) {
if (regex.location == "body" && bodyString) {
const match = bodyString.match(regex.regex)
if (match) {
for (const group of regex.publicGroups) {
matches.push({
name: regex.name,
match: match[group],
})
}
}
} else {
const match = headerString.match(regex.regex)
if (match) {
for (const group of regex.publicGroups) {
matches.push({
name: regex.name,
match: match[group],
})
}
}
}
}
return matches;
}

export async function extractMatchesWasm(headerString: string, bodyString: string | undefined, values: Values[]) {
let ready = await wasmLoaded;
let matches: {name: string, match: string}[] = [];
for (const value of values) {
if (value.location == "body" && bodyString) {
try {
let match = extractSubstr(bodyString, value, false)
if (match.length > 0) {
matches = matches.concat(match.map( (m:string) => {
return {
name: value.name,
match: m,
}
}));
}
} catch (e) {
console.error(e);
}
} else {
try {
let match = extractSubstr(headerString, value, false)
if (match.length > 0) {
matches = matches.concat(match.map( (m:string) => {
return {
name: value.name,
match: m,
}
}));
}
} catch (e) {
console.error(e);
}
}
}
return matches;
}
53 changes: 53 additions & 0 deletions packages/app/src/scripts/regex.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// import initWasm, { extractSubstr, extractSubstrIdxes } from "@zk-email/relayer-utils";
// import fs from "fs";

import { extractMatches, extractMatchesWasm } from "@/lib/regex"

// (async () => {
// const code = fs.readFileSync("node_modules/@zk-email/relayer-utils/relayer_utils_bg.wasm");
// await initWasm({module_or_path: code});
// const email = "subject:Congratulations mr x\r\n";
// const matches = extractSubstr(email, {
// parts: [
// {
// "is_public": false,
// "regex_def": "(\r\n|^)subject:"
// },
// {
// "is_public": true,
// "regex_def": "Congratulations"
// },
// {
// "is_public": false,
// "regex_def": "[^\r]+\r\n"
// }
// ]
// }, false)
// console.log(matches)
// })()

const matches = extractMatchesWasm("\r\nsubject:Congratulations mr x\r\n", "body", [{
name: "subject",
location: "header",
parts: [
{
"is_public": false,
"regex_def": "(\r\n|^)subject:"
},
{
"is_public": true,
"regex_def": "Congratulations"
},
{
"is_public": false,
"regex_def": "[^\r]+\r\n"
}
],
}, {name: "body", location: "body", parts: [
{
"is_public": true,
"regex_def": "body"
}
]}]).then((matches) => {
console.log(matches)
})
5 changes: 5 additions & 0 deletions packages/app/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2531,6 +2531,11 @@
psl "^1.9.0"
snarkjs "https://github.com/sampritipanda/snarkjs.git#fef81fc51d17a734637555c6edbd585ecda02d9e"

"@zk-email/relayer-utils@^0.4.2":
version "0.4.2"
resolved "https://registry.yarnpkg.com/@zk-email/relayer-utils/-/relayer-utils-0.4.2.tgz#8e13277c1c14ac7c17a0df60803eb8ab5a3d0091"
integrity sha512-IqJOQ75xou1H6LpTEekYMkSFtBKW2KNtCkbGVKg/vps3w3xso/qSzT8myHYKw7nm69bPRRMPVkhtFyyd33DDhQ==

"@zk-email/zk-email-sdk@^1.0.5":
version "1.0.5"
resolved "https://registry.yarnpkg.com/@zk-email/zk-email-sdk/-/zk-email-sdk-1.0.5.tgz#2ae9724653c652b87d0d9b62fcf12dc0a15ac545"
Expand Down

0 comments on commit 10b071d

Please sign in to comment.