-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Expand file tree
/
Copy pathutils.go
More file actions
78 lines (66 loc) · 2.44 KB
/
utils.go
File metadata and controls
78 lines (66 loc) · 2.44 KB
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
72
73
74
75
76
77
78
package apidef
import (
"errors"
"regexp"
)
var (
unicodeRegex = regexp.MustCompile(`\\u([0-9a-fA-F]{4})`)
re2Regex = regexp.MustCompile(`\\x\{([0-9a-fA-F]{4})}`)
)
type DataBytesModifier struct {
data []byte
}
func (d *DataBytesModifier) Result() []byte {
return d.data
}
func (d *DataBytesModifier) Reset() {
d.data = nil
}
func (d *DataBytesModifier) Data(data []byte) {
d.data = data
}
// TransformUnicodeEscapesToRE2 transforms ECMA-262 compliant Unicode escape sequences (`\uXXXX`)
// into a format that is compatible with Go's RE2 regex engine (`\x{XXXX}`).
// This is necessary because RE2 does not support the `\u` escape sequence but
// does support hexadecimal escapes, which can represent any Unicode code point.
// The function returns a new byte array with the transformed pattern.
func (d *DataBytesModifier) TransformUnicodeEscapesToRE2() {
d.data = unicodeRegex.ReplaceAllFunc(d.data, func(match []byte) []byte {
res := make([]byte, 0, 8)
res = append(res, `\x{`...)
res = append(res, match[2:]...)
res = append(res, `}`...)
return res
})
}
// RestoreUnicodeEscapesFromRE2 translates RE2-compatible hexadecimal escape
// sequences (`\x{XXXX}`) back to their original ECMA-262 compliant Unicode
// escape sequence representation (`\uXXXX`). This function is typically used
// when exporting an API definition or any other data structure where regex
// patterns were previously sanitized for internal use with Go's RE2 engine.
// It ensures that external consumers of the data receive the regex patterns
// in their original, more widely supported format.
func (d *DataBytesModifier) RestoreUnicodeEscapesFromRE2() {
d.data = re2Regex.ReplaceAllFunc(d.data, func(match []byte) []byte {
res := make([]byte, 0, 6)
res = append(res, `\u`...)
res = append(res, match[3:7]...)
return res
})
}
func NewDataBytesModifier(data []byte) *DataBytesModifier {
return &DataBytesModifier{data: data}
}
// RestoreUnicodeEscapesInError takes an error and applies the
// RestoreUnicodeEscapesInRegexp transformation to its message. For example,
// it converts RE2-compatible escapes like `\x{0041}` back to `\u0041`.
// It returns a new error with the transformed message. If the input error is nil,
// it returns nil.
func RestoreUnicodeEscapesInError(err error) error {
if err == nil {
return nil
}
modifier := NewDataBytesModifier([]byte(err.Error()))
modifier.RestoreUnicodeEscapesFromRE2()
return errors.New(string(modifier.Result()))
}