Fix overlapping capture groups
This commit is contained in:
@@ -208,6 +208,8 @@ func (p *RegexProcessor) ProcessContent(content string, pattern string, luaExpr
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
captureGroups = deduplicateGroups(captureGroups)
|
||||||
|
|
||||||
if err := p.ToLua(L, captureGroups); err != nil {
|
if err := p.ToLua(L, captureGroups); err != nil {
|
||||||
logger.Error("Failed to set Lua variables: %v", err)
|
logger.Error("Failed to set Lua variables: %v", err)
|
||||||
continue
|
continue
|
||||||
@@ -285,6 +287,14 @@ func (p *RegexProcessor) ProcessContent(content string, pattern string, luaExpr
|
|||||||
|
|
||||||
for _, command := range commands {
|
for _, command := range commands {
|
||||||
logger.Trace("Replace pos %d-%d with %q", command.From, command.To, command.With)
|
logger.Trace("Replace pos %d-%d with %q", command.From, command.To, command.With)
|
||||||
|
if command.To < command.From {
|
||||||
|
logger.Error("Command to is less than from: %v", command)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if command.From > len(replacement) || command.To > len(replacement) {
|
||||||
|
logger.Error("Command from or to is greater than replacement length: %v", command)
|
||||||
|
continue
|
||||||
|
}
|
||||||
replacement = replacement[:command.From] + command.With + replacement[command.To:]
|
replacement = replacement[:command.From] + command.With + replacement[command.To:]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -305,6 +315,30 @@ func (p *RegexProcessor) ProcessContent(content string, pattern string, luaExpr
|
|||||||
return result, modificationCount, len(indices), nil
|
return result, modificationCount, len(indices), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func deduplicateGroups(captureGroups []*CaptureGroup) []*CaptureGroup {
|
||||||
|
deduplicatedGroups := make([]*CaptureGroup, 0)
|
||||||
|
for _, group := range captureGroups {
|
||||||
|
overlaps := false
|
||||||
|
logger.Debug("Checking capture group: %s with range %v", group.Name, group.Range)
|
||||||
|
for _, existingGroup := range deduplicatedGroups {
|
||||||
|
logger.Debug("Comparing with existing group: %s with range %v", existingGroup.Name, existingGroup.Range)
|
||||||
|
if group.Range[0] < existingGroup.Range[1] && group.Range[1] > existingGroup.Range[0] {
|
||||||
|
overlaps = true
|
||||||
|
logger.Warning("Detected overlap between capture group '%s' and existing group '%s' in range %v-%v and %v-%v", group.Name, existingGroup.Name, group.Range[0], group.Range[1], existingGroup.Range[0], existingGroup.Range[1])
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if overlaps {
|
||||||
|
// We CAN just continue despite this fuckup
|
||||||
|
logger.Error("Overlapping capture group: %s", group.Name)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
logger.Debug("No overlap detected for capture group: %s. Adding to deduplicated groups.", group.Name)
|
||||||
|
deduplicatedGroups = append(deduplicatedGroups, group)
|
||||||
|
}
|
||||||
|
return deduplicatedGroups
|
||||||
|
}
|
||||||
|
|
||||||
// The order of these replaces is important
|
// The order of these replaces is important
|
||||||
// This one handles !num-s inside of named capture groups
|
// This one handles !num-s inside of named capture groups
|
||||||
// If it were not here our !num in a named capture group would
|
// If it were not here our !num in a named capture group would
|
||||||
|
@@ -3,6 +3,7 @@ package regression
|
|||||||
import (
|
import (
|
||||||
"modify/processor"
|
"modify/processor"
|
||||||
"os"
|
"os"
|
||||||
|
"path/filepath"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -83,13 +84,18 @@ func TestTalentsMechanicOutOfRange(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestIndexExplosions(t *testing.T) {
|
func TestIndexExplosions_ShouldNotPanic(t *testing.T) {
|
||||||
given, err := os.ReadFile("testfiles/OutpostItems.xml")
|
cwd, err := os.Getwd()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Error getting current working directory: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
given, err := os.ReadFile(filepath.Join(cwd, "..", "testfiles", "OutpostItems.xml"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Error reading file: %v", err)
|
t.Fatalf("Error reading file: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
expected, err := os.ReadFile("testfiles/OutpostItemsExpected.xml")
|
expected, err := os.ReadFile(filepath.Join(cwd, "..", "testfiles", "OutpostItemsExpected.xml"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Error reading file: %v", err)
|
t.Fatalf("Error reading file: %v", err)
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user