detached 0eecc37

fix(filtering): use local converter for thread-safe compilation

commit
0eecc37a138096273150bf0f17ceca64f05b84a0
author
bnema · · 2025-11-29 13:38 UTC
parent
55e3159
signature
GPG Unverified2B82207D370127A0 The key is unknown
1 file · +8 -12
M internal/filtering/compiler.go +8 -12
@@ -12,15 +12,11 @@ import (
1212 )
1313
1414 // DefaultFilterCompiler implements FilterCompiler using the converter package
15-type DefaultFilterCompiler struct {
16- converter *converter.FilterConverter
17-}
15+type DefaultFilterCompiler struct{}
1816
1917 // NewDefaultFilterCompiler creates a new default filter compiler
2018 func NewDefaultFilterCompiler() *DefaultFilterCompiler {
21- return &DefaultFilterCompiler{
22- converter: converter.NewFilterConverter(),
23- }
19+ return &DefaultFilterCompiler{}
2420 }
2521
2622 // CompileFromSources downloads and compiles filters from multiple URLs
@@ -53,8 +49,8 @@ func (dfc *DefaultFilterCompiler) CompileFromSources(ctx context.Context, source
5349 func (dfc *DefaultFilterCompiler) CompileFromData(data []byte) (*CompiledFilters, error) {
5450 compiled := NewCompiledFilters()
5551
56- // Reset converter for new compilation
57- dfc.converter = converter.NewFilterConverter()
52+ // Use local converter for thread safety (avoid shared state)
53+ conv := converter.NewFilterConverter()
5854
5955 // Parse line by line
6056 scanner := bufio.NewScanner(strings.NewReader(string(data)))
@@ -65,7 +61,7 @@ func (dfc *DefaultFilterCompiler) CompileFromData(data []byte) (*CompiledFilters
6561 lineCount++
6662
6763 // Convert each line
68- if err := dfc.converter.ConvertEasyListLine(line); err != nil {
64+ if err := conv.ConvertEasyListLine(line); err != nil {
6965 logging.Debug(fmt.Sprintf("Failed to convert filter line: %s, error: %v", line, err))
7066 continue
7167 }
@@ -76,9 +72,9 @@ func (dfc *DefaultFilterCompiler) CompileFromData(data []byte) (*CompiledFilters
7672 }
7773
7874 // Get compiled rules from converter
79- compiled.NetworkRules = dfc.converter.GetNetworkRules()
80- compiled.CosmeticRules = dfc.converter.GetCosmeticRules()
81- compiled.GenericHiding = dfc.converter.GetGenericHiding()
75+ compiled.NetworkRules = conv.GetNetworkRules()
76+ compiled.CosmeticRules = conv.GetCosmeticRules()
77+ compiled.GenericHiding = conv.GetGenericHiding()
8278 compiled.CompiledAt = time.Now()
8379 compiled.Version = fmt.Sprintf("data-compile-%d", time.Now().Unix())
8480
@@ -12,15 +12,11 @@ import (
12 )12 )
13 13
14 // DefaultFilterCompiler implements FilterCompiler using the converter package14 // DefaultFilterCompiler implements FilterCompiler using the converter package
15-type DefaultFilterCompiler struct {15+type DefaultFilterCompiler struct{}
16- converter *converter.FilterConverter
17-}
18 16
19 // NewDefaultFilterCompiler creates a new default filter compiler17 // NewDefaultFilterCompiler creates a new default filter compiler
20 func NewDefaultFilterCompiler() *DefaultFilterCompiler {18 func NewDefaultFilterCompiler() *DefaultFilterCompiler {
21- return &DefaultFilterCompiler{19+ return &DefaultFilterCompiler{}
22- converter: converter.NewFilterConverter(),
23- }
24 }20 }
25 21
26 // CompileFromSources downloads and compiles filters from multiple URLs22 // CompileFromSources downloads and compiles filters from multiple URLs
@@ -53,8 +49,8 @@ func (dfc *DefaultFilterCompiler) CompileFromSources(ctx context.Context, source
53 func (dfc *DefaultFilterCompiler) CompileFromData(data []byte) (*CompiledFilters, error) {49 func (dfc *DefaultFilterCompiler) CompileFromData(data []byte) (*CompiledFilters, error) {
54 compiled := NewCompiledFilters()50 compiled := NewCompiledFilters()
55 51
56- // Reset converter for new compilation52+ // Use local converter for thread safety (avoid shared state)
57- dfc.converter = converter.NewFilterConverter()53+ conv := converter.NewFilterConverter()
58 54
59 // Parse line by line55 // Parse line by line
60 scanner := bufio.NewScanner(strings.NewReader(string(data)))56 scanner := bufio.NewScanner(strings.NewReader(string(data)))
@@ -65,7 +61,7 @@ func (dfc *DefaultFilterCompiler) CompileFromData(data []byte) (*CompiledFilters
65 lineCount++61 lineCount++
66 62
67 // Convert each line63 // Convert each line
68- if err := dfc.converter.ConvertEasyListLine(line); err != nil {64+ if err := conv.ConvertEasyListLine(line); err != nil {
69 logging.Debug(fmt.Sprintf("Failed to convert filter line: %s, error: %v", line, err))65 logging.Debug(fmt.Sprintf("Failed to convert filter line: %s, error: %v", line, err))
70 continue66 continue
71 }67 }
@@ -76,9 +72,9 @@ func (dfc *DefaultFilterCompiler) CompileFromData(data []byte) (*CompiledFilters
76 }72 }
77 73
78 // Get compiled rules from converter74 // Get compiled rules from converter
79- compiled.NetworkRules = dfc.converter.GetNetworkRules()75+ compiled.NetworkRules = conv.GetNetworkRules()
80- compiled.CosmeticRules = dfc.converter.GetCosmeticRules()76+ compiled.CosmeticRules = conv.GetCosmeticRules()
81- compiled.GenericHiding = dfc.converter.GetGenericHiding()77+ compiled.GenericHiding = conv.GetGenericHiding()
82 compiled.CompiledAt = time.Now()78 compiled.CompiledAt = time.Now()
83 compiled.Version = fmt.Sprintf("data-compile-%d", time.Now().Unix())79 compiled.Version = fmt.Sprintf("data-compile-%d", time.Now().Unix())
84 80

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 8

Tags 42

↑↓ moveenter openesc close