#208 - Added a time limits for regex matchers
This commit is contained in:
@@ -14,6 +14,7 @@ import {
|
||||
splitCamelCase,
|
||||
stringsToRegex,
|
||||
stripMarkdownCharacters,
|
||||
warnDebug,
|
||||
} from '../tools/utils'
|
||||
import { Notice } from 'obsidian'
|
||||
import type { Query } from './query'
|
||||
@@ -144,11 +145,11 @@ export class Omnisearch {
|
||||
logDebug('Indexing into search engine', docs)
|
||||
// Update the list of indexed docs
|
||||
docs.forEach(doc => this.indexedDocuments.set(doc.path, doc.mtime))
|
||||
|
||||
|
||||
// Discard files that may have been already added (though it shouldn't happen)
|
||||
const alreadyAdded = docs.filter(doc => this.minisearch.has(doc.path))
|
||||
this.removeFromPaths(alreadyAdded.map(o => o.path))
|
||||
|
||||
|
||||
// Add docs to minisearch
|
||||
await this.minisearch.addAllAsync(docs)
|
||||
}
|
||||
@@ -304,11 +305,16 @@ export class Omnisearch {
|
||||
}
|
||||
|
||||
public getMatches(text: string, reg: RegExp, query: Query): SearchMatch[] {
|
||||
const startTime = new Date().getTime()
|
||||
let match: RegExpExecArray | null = null
|
||||
const matches: SearchMatch[] = []
|
||||
let count = 0
|
||||
while ((match = reg.exec(text)) !== null) {
|
||||
if (++count >= 100) break // Avoid infinite loops, stop looking after 100 matches
|
||||
// Avoid infinite loops, stop looking after 100 matches or if we're taking too much time
|
||||
if (++count >= 100 || new Date().getTime() - startTime > 50) {
|
||||
warnDebug('Stopped getMatches at', count, 'results')
|
||||
break
|
||||
}
|
||||
const m = match[0]
|
||||
if (m) matches.push({ match: m, offset: match.index })
|
||||
}
|
||||
|
||||
@@ -325,8 +325,18 @@ export function splitCamelCase(text: string): string[] {
|
||||
return text.replace(/([a-z](?=[A-Z]))/g, '$1 ').split(' ')
|
||||
}
|
||||
|
||||
export function logDebug(...attr: any[]): void {
|
||||
export function logDebug(...args: any[]): void {
|
||||
printDebug(console.log, ...args)
|
||||
}
|
||||
|
||||
export function warnDebug(...args: any[]): void {
|
||||
printDebug(console.warn, ...args)
|
||||
}
|
||||
|
||||
function printDebug(fn: (...args: any[]) => any, ...args: any[]): void {
|
||||
if (settings.verboseLogging) {
|
||||
console.log(...['Omnisearch -', ...attr])
|
||||
const t = new Date()
|
||||
const ts = `${t.getMinutes()}:${t.getSeconds()}:${t.getMilliseconds()}`
|
||||
fn(...['Omnisearch -', ts + ' -', ...args])
|
||||
}
|
||||
}
|
||||
|
||||
25
src/vendor/parse-query.ts
vendored
25
src/vendor/parse-query.ts
vendored
@@ -6,6 +6,8 @@
|
||||
* MIT Licensed
|
||||
*/
|
||||
|
||||
import { warnDebug } from "../tools/utils";
|
||||
|
||||
interface SearchParserOptions {
|
||||
offsets?: boolean
|
||||
tokenize: true
|
||||
@@ -30,7 +32,7 @@ type SearchParserTextOffset = {
|
||||
type SearchParserOffset = (
|
||||
| SearchParserKeyWordOffset
|
||||
| SearchParserTextOffset
|
||||
) & {
|
||||
) & {
|
||||
offsetStart: number
|
||||
offsetEnd: number
|
||||
}
|
||||
@@ -43,7 +45,7 @@ interface SearchParserResult extends ISearchParserDictionary {
|
||||
|
||||
export function parseQuery(
|
||||
string: string,
|
||||
options: SearchParserOptions
|
||||
options: SearchParserOptions,
|
||||
): SearchParserResult {
|
||||
// Set a default options object when none is provided
|
||||
if (!options) {
|
||||
@@ -74,9 +76,14 @@ export function parseQuery(
|
||||
const regex =
|
||||
/(\S+:'(?:[^'\\]|\\.)*')|(\S+:"(?:[^"\\]|\\.)*")|(-?"(?:[^"\\]|\\.)*")|(-?'(?:[^'\\]|\\.)*')|\S+|\S+:\S+/g
|
||||
let match
|
||||
let count = 0 // TODO: FIXME: this is a hack to avoid infinite loops
|
||||
let count = 0
|
||||
const startTime = new Date().getTime()
|
||||
|
||||
while ((match = regex.exec(string)) !== null) {
|
||||
if (++count >= 100) break
|
||||
if (++count >= 100 || new Date().getTime() - startTime > 50) {
|
||||
warnDebug('Stopped SearchParserResult at', count, 'results')
|
||||
break
|
||||
}
|
||||
let term = match[0]
|
||||
const sepIndex = term.indexOf(':')
|
||||
|
||||
@@ -291,11 +298,11 @@ export function parseQuery(
|
||||
query[key].from = rangeValues[0]
|
||||
query[key].to = rangeValues[1]
|
||||
}
|
||||
// When pairs of ranges are specified
|
||||
// keyword:XXXX-YYYY,AAAA-BBBB
|
||||
// else if (!rangeValues.length % 2) {
|
||||
// }
|
||||
// When only getting a single value,
|
||||
// When pairs of ranges are specified
|
||||
// keyword:XXXX-YYYY,AAAA-BBBB
|
||||
// else if (!rangeValues.length % 2) {
|
||||
// }
|
||||
// When only getting a single value,
|
||||
// or an odd number of values
|
||||
else {
|
||||
query[key].from = value
|
||||
|
||||
Reference in New Issue
Block a user