From d6d130dbba2fcea78109ca647f552ba8fc57a39d Mon Sep 17 00:00:00 2001 From: qwertyforce <44163887+qwertyforce@users.noreply.github.com> Date: Sat, 26 Dec 2020 12:56:08 +0300 Subject: [PATCH] Update search.tsx --- pages/search.tsx | 209 +++++++++++++++++++++++++++++------------------ 1 file changed, 129 insertions(+), 80 deletions(-) diff --git a/pages/search.tsx b/pages/search.tsx index 5e5e2d5..8cfe2f2 100644 --- a/pages/search.tsx +++ b/pages/search.tsx @@ -47,9 +47,7 @@ export default function Search(props: any) { ) } - - -function parse(query:string) { +function parse(tokens: string[]) { const operators: any = [] const operands: any = [] const priority: any = { @@ -58,8 +56,8 @@ function parse(query:string) { "||": 1 } function operate(operator: string, a: any, b: any = 0) { - if(a===undefined || b===undefined){ - return {error:true} + if (a === undefined || b === undefined) { + return { error: true } } let x = {} switch (operator) { @@ -122,71 +120,9 @@ function parse(query:string) { } } } - function detect_brackets(str:string) { - const tokens = ["&&", "||", "!", ",","-"] - const tokens2 = ["&&", "||", "!", "(", ")", ",","-"] - const stack=[] - const closing_brackets=[] - const opening_brackets=[] - for(let i=0;i0 && (tokens.includes(str[x.idx-1])) || (str[x.idx-2] && tokens.includes(str[x.idx-2]+str[x.idx-1]))) || - (x.idx===0)){ - closing_brackets.push(i) - opening_brackets.push(x.idx) - }else if(m){ - closing_brackets.push(i) - opening_brackets.push(x.idx) - } - } - } - const arr=str.split("") - for(let i=0;iel.trim()).filter((el:any) => el !== "") - for(let i=0;i 0 && str[i] === ")") { + let x = stack.pop(); + let m = false; + if (!x) { + return "##errror##" + } + while (x.token !== "(") { + x = stack.pop(); + if (!x) { + return "##errror##" + } + if (tokens.includes(x.token)) { + m = true; + } + } + if (!m && (x.idx > 0 && (tokens.includes(str[x.idx - 1])) || (str[x.idx - 2] && tokens.includes(str[x.idx - 2] + str[x.idx - 1]))) || + (x.idx === 0)) { + closing_brackets.push(i); + opening_brackets.push(x.idx); + } + else if (m) { + closing_brackets.push(i); + opening_brackets.push(x.idx); + } + } + } + const arr = str.split(""); + for (let i = 0; i < closing_brackets.length; i++) { + arr[opening_brackets[i]] = "(%"; + arr[closing_brackets[i]] = "%)"; + } + str = arr.join(""); + return str; + } + function not_operator_fix(str: string) { + const str_arr = str.split(""); + const tokens = ["&&", "||", "!", ",", "-", "(", ")"]; + const not_operators = ["!", "-"]; + const stack = []; + for (let i = 0; i < str.length; i++) { + if (tokens.includes(str[i])) { + stack.push({ token: str[i], idx: i }); + } + if (str[i + 1] && tokens.includes(str[i] + str[i + 1])) { + stack.push({ token: str[i] + str[i + 1], idx: i }); + } + } + if (stack[0] && stack[0].idx === 0 && not_operators.includes(stack[0].token)) { + str_arr[0] = "#" + stack[0].token; + } + for (let i = 1; i < stack.length; i++) { + if (not_operators.includes(stack[i].token)) { + if (stack[i - 1].token !== ")" && stack[i - 1].token.length + stack[i - 1].idx === stack[i].idx) { + str_arr[stack[i].idx] = "#" + stack[i].token; + } + } + } + return str_arr.join(""); + } + function split(str: string) { + const operators = ["&&", "||", "#!", "(%", "%)", ",", "#-"]; + const temp_char = "#$#"; + str = not_operator_fix(str); + str = detect_brackets(str); + if (str === "##errror##") { + return [] + } + for (const operator of operators) { + str = str.replaceAll(operator, temp_char + operator + temp_char); + } + const arr = str.split(temp_char).map((el) => el.trim()).filter((el) => el !== ""); + for (let i = 0; i < arr.length; i++) { + if (arr[i] === "(%") { + arr[i] = "("; + } + if (arr[i] === "#-") { + arr[i] = "-"; + } + if (arr[i] === "#!") { + arr[i] = "!"; + } + if (arr[i] === "%)") { + arr[i] = ")"; + } + } + console.log(arr); + return arr; + } + return split(query) +} +function build_ast(str: string) { + const tokens = tokenize(str) + if (tokens.length === 0) { + return { error: true } + } + const ast = parse(tokens) + return ast +} + // eslint-disable-next-line @typescript-eslint/no-explicit-any export async function getServerSideProps(context: any) { if (context.query.q) { - if(context.query.q.includes("$")){ + if (context.query.q.includes("$")) { //anti - nosql injection or something return { - props: { err: true } + props: { err: true } } } console.log(context.query.q) - const query=parse(context.query.q) - if(query.error){ + const query = build_ast(context.query.q) + if (query.error) { return { - props: { err: true } + props: { err: true } } } const images = await db_ops.image_ops.find_images_by_tags(query) @@ -242,7 +291,7 @@ export async function getServerSideProps(context: any) { } else { page = 1 } - page = Math.max(page,1) + page = Math.max(page, 1) if (page <= Math.ceil(images.length / images_on_page)) { for (let i = (page - 1) * images_on_page; (i < (page) * images_on_page) && (i < images.length); i++) { photos.push({ @@ -263,6 +312,6 @@ export async function getServerSideProps(context: any) { } } return { - props: { err: true } + props: { err: true } } } \ No newline at end of file