diff --git a/src/components/profile/rules-editor-viewer.tsx b/src/components/profile/rules-editor-viewer.tsx index 4c8e26e6..e1fb272e 100644 --- a/src/components/profile/rules-editor-viewer.tsx +++ b/src/components/profile/rules-editor-viewer.tsx @@ -217,6 +217,31 @@ export const RulesEditorViewer = (props: Props) => { fetchProfile(); }, [open]); + const spliceRule = () => { + if (ruleContent === "") return ""; + // Check valid by regex + switch (ruleType) { + case "IP-CIDR": { + let v4regex = new RegExp( + "^((?:(?:[1-9]?[0-9]|1[0-9][0-9]|2(?:[0-4][0-9]|5[0-5]))\\.){3}(?:[1-9]?[0-9]|1[0-9][0-9]|2(?:[0-4][0-9]|5[0-5])))?:(?:[0-9]|[1-9][0-9]{1,3}|[1-5][0-9]{4}|6[0-5]{2}[0-3][0-5])$" + ); + let v6regex = new RegExp( + "^([0-9a-fA-F]{1,4}(?::[0-9a-fA-F]{1,4}){7}|::|:(?::[0-9a-fA-F]{1,4}){1,6}|[0-9a-fA-F]{1,4}:(?::[0-9a-fA-F]{1,4}){1,5}|(?:[0-9a-fA-F]{1,4}:){2}(?::[0-9a-fA-F]{1,4}){1,4}|(?:[0-9a-fA-F]{1,4}:){3}(?::[0-9a-fA-F]{1,4}){1,3}|(?:[0-9a-fA-F]{1,4}:){4}(?::[0-9a-fA-F]{1,4}){1,2}|(?:[0-9a-fA-F]{1,4}:){5}:[0-9a-fA-F]{1,4}|(?:[0-9a-fA-F]{1,4}:){1,6}:)\\/(?:12[0-8]|1[01][0-9]|[1-9]?[0-9])$" + ); + if (!v4regex.test(ruleContent) && !v6regex.test(ruleContent)) return ""; + + break; + } + default: + break; + } + return `${ruleType}${ + ruleType === "MATCH" ? "" : "," + ruleContent + },${proxyPolicy}${ + NoResolveList.includes(ruleType) && noResolve ? ",no-resolve" : "" + }`; + }; + const onSave = useLockFn(async () => { try { let currData = yaml.dump({ @@ -325,13 +350,11 @@ export const RulesEditorViewer = (props: Props) => { fullWidth variant="contained" onClick={() => { - let raw = `${ruleType}${ - ruleType === "MATCH" ? "" : "," + ruleContent - },${proxyPolicy}${ - NoResolveList.includes(ruleType) && noResolve - ? ",no-resolve" - : "" - }`; + let raw = spliceRule(); + if (raw === "") { + Notice.error(t("Invalid Rule")); + return; + } if (prependSeq.includes(raw)) return; setPrependSeq([...prependSeq, raw]); }} @@ -344,13 +367,11 @@ export const RulesEditorViewer = (props: Props) => { fullWidth variant="contained" onClick={() => { - let raw = `${ruleType}${ - ruleType === "MATCH" ? "" : "," + ruleContent - },${proxyPolicy}${ - NoResolveList.includes(ruleType) && noResolve - ? ",no-resolve" - : "" - }`; + let raw = spliceRule(); + if (raw === "") { + Notice.error(t("Invalid Rule")); + return; + } if (appendSeq.includes(raw)) return; setAppendSeq([...appendSeq, raw]); }} diff --git a/src/locales/en.json b/src/locales/en.json index 1d5094e4..1117e4ee 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -58,6 +58,7 @@ "No Resolve": "No Resolve", "Add Prepend Rule": "Add Prepend Rule", "Add Append Rule": "Add Append Rule", + "Invalid Rule": "Invalid Rule", "Delete Rule": "Delete Rule", "Edit Groups": "Edit Proxy Groups", "Extend Config": "Extend Config", diff --git a/src/locales/zh.json b/src/locales/zh.json index ddd9b3c4..18fe8ec7 100644 --- a/src/locales/zh.json +++ b/src/locales/zh.json @@ -58,6 +58,7 @@ "No Resolve": "跳过DNS解析", "Add Prepend Rule": "添加前置规则", "Add Append Rule": "添加后置规则", + "Invalid Rule": "无效规则", "Delete Rule": "删除规则", "Edit Groups": "编辑代理组", "Extend Config": "扩展配置",