From 1faee002a9f3ad8ca1d637ab83957c629a9b004c Mon Sep 17 00:00:00 2001 From: Alikia2x Date: Sat, 27 Apr 2024 16:58:37 +0800 Subject: [PATCH] improve: better base64 check, with test --- components/search/onesearch/handleEnter.ts | 2 +- components/search/onesearch/onesearch.tsx | 31 +++++++++++++-------- components/search/onesearch/plainSearch.tsx | 4 +-- lib/nlp/extract.ts | 7 +++++ lib/onesearch/baseCheck.tsx | 10 +++++-- test/base64.test.ts | 11 ++++++++ 6 files changed, 47 insertions(+), 18 deletions(-) create mode 100644 lib/nlp/extract.ts create mode 100644 test/base64.test.ts diff --git a/components/search/onesearch/handleEnter.ts b/components/search/onesearch/handleEnter.ts index d77191c..d8db052 100644 --- a/components/search/onesearch/handleEnter.ts +++ b/components/search/onesearch/handleEnter.ts @@ -16,7 +16,7 @@ export default function ( let clipboard: any; if (selected.type === "QUERY" || selected.type === "default") { search(selected.suggestion, engine, newTab); - } else if (selected.type === "NAVIGATION") { + } else if (selected.type === "NAVIGATION" || selected.type === "default-link") { window.open(normalizeURL(selected.suggestion)); } else if (selected.type === "text") { console.log("????"); diff --git a/components/search/onesearch/onesearch.tsx b/components/search/onesearch/onesearch.tsx index 5192f99..a727813 100644 --- a/components/search/onesearch/onesearch.tsx +++ b/components/search/onesearch/onesearch.tsx @@ -13,13 +13,14 @@ import { selectedSuggestionState } from "@/components/state/suggestionSelection" import { settingsState } from "@/components/state/settings"; import { base64NLP } from "@/lib/onesearch/baseCheck"; import PlainText from "./plainText"; +import { sendError } from "@/lib/telemetering/sendError"; export default function () { const [suggestion, setFinalSuggetsion] = useRecoilState(suggestionsState); const lastRequestTimeRef = useRef(0); const selected = useRecoilValue(selectedSuggestionState); const settings = useRecoilValue(settingsState); - const devMode = true; + const devMode = false; const query = useRecoilValue(queryState); const engineName = getSearchEngineName(); const engine = settings.currentSearchEngine; @@ -28,19 +29,27 @@ export default function () { useEffect(() => { const time = new Date().getTime().toString(); - if (query.trim() === "") { + if (query.trim() === "" || query.length > 120) { cleanSuggestion("QUERY", "NAVIGATION"); return; } fetch(`/api/suggestion?q=${query}&l=${lang}&t=${time}&engine=${engine}`) .then((res) => res.json()) .then((data: suggestionsResponse) => { - let suggestionToUpdate: suggestionItem[] = data.suggestions; - if (data.time > lastRequestTimeRef.current) { - cleanSuggestion("NAVIGATION", "QUERY"); - lastRequestTimeRef.current = data.time; - updateSuggestion(suggestionToUpdate); + try { + let suggestionToUpdate: suggestionItem[] = data.suggestions; + if (data.time > lastRequestTimeRef.current) { + cleanSuggestion("NAVIGATION", "QUERY"); + lastRequestTimeRef.current = data.time; + updateSuggestion(suggestionToUpdate); + } + } catch (error: Error | any) { + sendError(error); } + }) + .catch((error) => { + // Handle fetch error + sendError(error); }); }, [query]); @@ -73,7 +82,7 @@ export default function () { cleanSuggestion("default-link", "default", "text"); if (validLink(query)) { updateSuggestion([ - { type: "default-link", suggestion: query, relevance: 3000 }, + { type: "default-link", suggestion: query, relevance: 3000, prompt: Go to: }, { type: "default", suggestion: query, relevance: 1600 } ]); } else { @@ -86,7 +95,6 @@ export default function () { ]); } const b64 = base64NLP(query); - console.log(base64NLP(query)); if (b64.suggestion !== null) { updateSuggestion([b64 as suggestionItem]); } @@ -124,6 +132,7 @@ export default function () { } else if (s.type === "NAVIGATION" || s.type === "default-link") { return ( + {s.prompt && {s.prompt}} {s.suggestion} {devMode && ( @@ -135,9 +144,7 @@ export default function () { } else if (s.type === "text") { return ( - {s.prompt && ( - <span className="text-zinc-700 dark:text-zinc-400">{s.prompt}</span> - )} + {s.prompt && <span className="text-zinc-700 dark:text-zinc-400">{s.prompt}</span>} <p>{s.suggestion}</p> {devMode && ( <span className="text-zinc-700 dark:text-zinc-400 text-sm"> diff --git a/components/search/onesearch/plainSearch.tsx b/components/search/onesearch/plainSearch.tsx index c8deb7e..79d43d1 100644 --- a/components/search/onesearch/plainSearch.tsx +++ b/components/search/onesearch/plainSearch.tsx @@ -10,7 +10,7 @@ export default function (props: { children: React.ReactNode; query: string; sele return ( <div className={`w-full h-10 leading-10 bg-zinc-300 dark:bg-zinc-700 - px-5 z-10 cursor-pointer duration-100`} + px-5 z-10 cursor-pointer duration-100 truncate`} onClick={() => { search(props.query, engine, newTab); }} @@ -23,7 +23,7 @@ export default function (props: { children: React.ReactNode; query: string; sele return ( <div className={`w-full h-10 leading-10 bg-zinc-100 hover:bg-zinc-300 - dark:bg-zinc-800 hover:dark:bg-zinc-700 px-5 z-10 cursor-pointer duration-100`} + dark:bg-zinc-800 hover:dark:bg-zinc-700 px-5 z-10 cursor-pointer duration-100 truncate`} onClick={() => { search(props.query, engine, newTab); }} diff --git a/lib/nlp/extract.ts b/lib/nlp/extract.ts new file mode 100644 index 0000000..50024f9 --- /dev/null +++ b/lib/nlp/extract.ts @@ -0,0 +1,7 @@ +export default function slotExtract(str: string, keywords: string[]) { + let r = str; + for (let keyword of keywords) { + r = r.replace(keyword, ""); + } + return r.trim(); +} diff --git a/lib/onesearch/baseCheck.tsx b/lib/onesearch/baseCheck.tsx index 2e34c8c..4b12836 100644 --- a/lib/onesearch/baseCheck.tsx +++ b/lib/onesearch/baseCheck.tsx @@ -1,3 +1,4 @@ +import slotExtract from "../nlp/extract"; import removeStopwords from "../nlp/stopwords"; import { NLPResult } from "./NLPResult"; import {Kbd} from "@nextui-org/react"; @@ -47,7 +48,10 @@ export function base64NLP(str: string) { let processedQuery = str; if (result.intention==="base64.encode"){ - processedQuery = removeStopwords(str, Object.keys(keywords).concat(Object.keys(intentions)), true).trim(); + const blacklist = Object.keys(keywords).concat(Object.keys(intentions)).concat([ + "convert", "turn" + ]); + processedQuery = slotExtract(str,blacklist); } else if (result.intention==="base64.decode") { processedQuery = removeStopwords(str, Object.keys(keywords).concat(Object.keys(intentions))).trim(); } @@ -61,8 +65,8 @@ export function base64NLP(str: string) { else if (validBase64(processedQuery) && result.intention !== "base64.encode") { console.log("!!"); result.intention = "base64.decode"; - result.confidence += Math.max(1 / Math.log10(1 / processedQuery.length) + 1, 0); - result.probability += Math.max(1 / Math.log10(1 / processedQuery.length) + 1, 0); + result.confidence += Math.max(1 / Math.log2(1 / processedQuery.length) + 1, 0); + result.probability += Math.max(1 / Math.log2(1 / processedQuery.length) + 1, 0); } switch (result.intention) { diff --git a/test/base64.test.ts b/test/base64.test.ts new file mode 100644 index 0000000..26aacc2 --- /dev/null +++ b/test/base64.test.ts @@ -0,0 +1,11 @@ +import { base64NLP } from "@/lib/onesearch/baseCheck"; +import { describe, expect, test } from "@jest/globals"; + +describe("To auto-detect the intention of decoding an base64 string", () => { + test("Implicit declaration", () => { + expect(base64NLP("base64 encode encode MjM6MjQgQXByIDI1LCAyMDI0").intention).toBe("base64.encode"); + expect(base64NLP("base64 encode encode MjM6MjQgQXByIDI1LCAyMDI0").suggestion).toBe( + "ZW5jb2RlIE1qTTZNalFnUVhCeUlESTFMQ0F5TURJMA==" + ); + }); +});