-
Notifications
You must be signed in to change notification settings - Fork 0
/
string.ts
71 lines (52 loc) · 1.58 KB
/
string.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
export function truncate(str: string, maxLength: number): string {
if (str.length > maxLength) return `${str.slice(0, maxLength - 1)}…`
return str
}
export function regexReplace(string: string, regex: RegExp, replacer: (match: string, ...groups: string[]) => string): string {
const match = string.match(regex)
if (!match) return string
let resultString = ``
while (string.length) {
const match = string.match(regex)
if (!match) {
resultString += string
string = ``
continue
}
const completeMatch = match[0]
const groups = match.slice(1)
const newValue = replacer(completeMatch, ...groups)
resultString += `${string.slice(0, match.index)}${newValue}`
string = string.slice(match.index! + completeMatch.length)
}
return resultString
}
/** Concatenates two strings in such a way that path delimiter attacks cannot occur */
export function concatenate(sections: string[]): string {
return sections.map((section) => section.replaceAll('\\', '\\\\').replaceAll('/', '\\/')).join('/')
}
/** Slices a string concatenated with `concat` into an array of sections */
export function sliceConcatenated(concatenated: string): string[] {
const sections: string[] = []
let isEscaped = false
let currentSection = ''
for (const char of concatenated.split('')) {
if (isEscaped) {
isEscaped = false
currentSection += char
continue
}
if (char === '\\') {
isEscaped = true
continue
}
if (char === '/') {
sections.push(currentSection)
currentSection = ''
continue
}
currentSection += char
}
sections.push(currentSection)
return sections
}