improve: better base64 check, with test

This commit is contained in:
Alikia2x 2024-04-27 16:58:37 +08:00
parent 38b144a6f4
commit 1faee002a9
6 changed files with 47 additions and 18 deletions

View File

@ -16,7 +16,7 @@ export default function (
let clipboard: any; let clipboard: any;
if (selected.type === "QUERY" || selected.type === "default") { if (selected.type === "QUERY" || selected.type === "default") {
search(selected.suggestion, engine, newTab); search(selected.suggestion, engine, newTab);
} else if (selected.type === "NAVIGATION") { } else if (selected.type === "NAVIGATION" || selected.type === "default-link") {
window.open(normalizeURL(selected.suggestion)); window.open(normalizeURL(selected.suggestion));
} else if (selected.type === "text") { } else if (selected.type === "text") {
console.log("????"); console.log("????");

View File

@ -13,13 +13,14 @@ import { selectedSuggestionState } from "@/components/state/suggestionSelection"
import { settingsState } from "@/components/state/settings"; import { settingsState } from "@/components/state/settings";
import { base64NLP } from "@/lib/onesearch/baseCheck"; import { base64NLP } from "@/lib/onesearch/baseCheck";
import PlainText from "./plainText"; import PlainText from "./plainText";
import { sendError } from "@/lib/telemetering/sendError";
export default function () { export default function () {
const [suggestion, setFinalSuggetsion] = useRecoilState(suggestionsState); const [suggestion, setFinalSuggetsion] = useRecoilState(suggestionsState);
const lastRequestTimeRef = useRef(0); const lastRequestTimeRef = useRef(0);
const selected = useRecoilValue(selectedSuggestionState); const selected = useRecoilValue(selectedSuggestionState);
const settings = useRecoilValue(settingsState); const settings = useRecoilValue(settingsState);
const devMode = true; const devMode = false;
const query = useRecoilValue(queryState); const query = useRecoilValue(queryState);
const engineName = getSearchEngineName(); const engineName = getSearchEngineName();
const engine = settings.currentSearchEngine; const engine = settings.currentSearchEngine;
@ -28,19 +29,27 @@ export default function () {
useEffect(() => { useEffect(() => {
const time = new Date().getTime().toString(); const time = new Date().getTime().toString();
if (query.trim() === "") { if (query.trim() === "" || query.length > 120) {
cleanSuggestion("QUERY", "NAVIGATION"); cleanSuggestion("QUERY", "NAVIGATION");
return; return;
} }
fetch(`/api/suggestion?q=${query}&l=${lang}&t=${time}&engine=${engine}`) fetch(`/api/suggestion?q=${query}&l=${lang}&t=${time}&engine=${engine}`)
.then((res) => res.json()) .then((res) => res.json())
.then((data: suggestionsResponse) => { .then((data: suggestionsResponse) => {
try {
let suggestionToUpdate: suggestionItem[] = data.suggestions; let suggestionToUpdate: suggestionItem[] = data.suggestions;
if (data.time > lastRequestTimeRef.current) { if (data.time > lastRequestTimeRef.current) {
cleanSuggestion("NAVIGATION", "QUERY"); cleanSuggestion("NAVIGATION", "QUERY");
lastRequestTimeRef.current = data.time; lastRequestTimeRef.current = data.time;
updateSuggestion(suggestionToUpdate); updateSuggestion(suggestionToUpdate);
} }
} catch (error: Error | any) {
sendError(error);
}
})
.catch((error) => {
// Handle fetch error
sendError(error);
}); });
}, [query]); }, [query]);
@ -73,7 +82,7 @@ export default function () {
cleanSuggestion("default-link", "default", "text"); cleanSuggestion("default-link", "default", "text");
if (validLink(query)) { if (validLink(query)) {
updateSuggestion([ updateSuggestion([
{ type: "default-link", suggestion: query, relevance: 3000 }, { type: "default-link", suggestion: query, relevance: 3000, prompt: <span>Go to: </span> },
{ type: "default", suggestion: query, relevance: 1600 } { type: "default", suggestion: query, relevance: 1600 }
]); ]);
} else { } else {
@ -86,7 +95,6 @@ export default function () {
]); ]);
} }
const b64 = base64NLP(query); const b64 = base64NLP(query);
console.log(base64NLP(query));
if (b64.suggestion !== null) { if (b64.suggestion !== null) {
updateSuggestion([b64 as suggestionItem]); updateSuggestion([b64 as suggestionItem]);
} }
@ -124,6 +132,7 @@ export default function () {
} else if (s.type === "NAVIGATION" || s.type === "default-link") { } else if (s.type === "NAVIGATION" || s.type === "default-link") {
return ( return (
<Link key={i} query={s.suggestion} selected={i == selected}> <Link key={i} query={s.suggestion} selected={i == selected}>
{s.prompt && <span className="text-zinc-700 dark:text-zinc-400">{s.prompt}</span>}
{s.suggestion} {s.suggestion}
{devMode && ( {devMode && (
<span className="text-zinc-700 dark:text-zinc-400 text-sm"> <span className="text-zinc-700 dark:text-zinc-400 text-sm">
@ -135,9 +144,7 @@ export default function () {
} else if (s.type === "text") { } else if (s.type === "text") {
return ( return (
<PlainText key={i} selected={i == selected}> <PlainText key={i} selected={i == selected}>
{s.prompt && ( {s.prompt && <span className="text-zinc-700 dark:text-zinc-400">{s.prompt}</span>}
<span className="text-zinc-700 dark:text-zinc-400">{s.prompt}</span>
)}
<p>{s.suggestion}</p> <p>{s.suggestion}</p>
{devMode && ( {devMode && (
<span className="text-zinc-700 dark:text-zinc-400 text-sm"> <span className="text-zinc-700 dark:text-zinc-400 text-sm">

View File

@ -10,7 +10,7 @@ export default function (props: { children: React.ReactNode; query: string; sele
return ( return (
<div <div
className={`w-full h-10 leading-10 bg-zinc-300 dark:bg-zinc-700 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={() => { onClick={() => {
search(props.query, engine, newTab); search(props.query, engine, newTab);
}} }}
@ -23,7 +23,7 @@ export default function (props: { children: React.ReactNode; query: string; sele
return ( return (
<div <div
className={`w-full h-10 leading-10 bg-zinc-100 hover:bg-zinc-300 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={() => { onClick={() => {
search(props.query, engine, newTab); search(props.query, engine, newTab);
}} }}

7
lib/nlp/extract.ts Normal file
View File

@ -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();
}

View File

@ -1,3 +1,4 @@
import slotExtract from "../nlp/extract";
import removeStopwords from "../nlp/stopwords"; import removeStopwords from "../nlp/stopwords";
import { NLPResult } from "./NLPResult"; import { NLPResult } from "./NLPResult";
import {Kbd} from "@nextui-org/react"; import {Kbd} from "@nextui-org/react";
@ -47,7 +48,10 @@ export function base64NLP(str: string) {
let processedQuery = str; let processedQuery = str;
if (result.intention==="base64.encode"){ 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") { } else if (result.intention==="base64.decode") {
processedQuery = removeStopwords(str, Object.keys(keywords).concat(Object.keys(intentions))).trim(); 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") { else if (validBase64(processedQuery) && result.intention !== "base64.encode") {
console.log("!!"); console.log("!!");
result.intention = "base64.decode"; result.intention = "base64.decode";
result.confidence += 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.log10(1 / processedQuery.length) + 1, 0); result.probability += Math.max(1 / Math.log2(1 / processedQuery.length) + 1, 0);
} }
switch (result.intention) { switch (result.intention) {

11
test/base64.test.ts Normal file
View File

@ -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=="
);
});
});