fix(translate): M1-M3 medium + L1-L2 low bugs from QA review
M1: ReDoS guard — 500 char max + try/except on re.compile M2: Performance note — O(n×m) regex documented for future optimization M3: Verified test key names correct (metrics.py transforms cumulative_* → short) L1: Removed @staticmethod no-op from module-level function L2: Added aria-label to emoji indicators in CorrectionCell
This commit is contained in:
@@ -658,6 +658,10 @@ class DictionaryManager:
|
||||
if not all_entries:
|
||||
return []
|
||||
|
||||
# PERFORMANCE NOTE: O(rows × entries) regex matching per batch.
|
||||
# Acceptable for current scale (50-100 rows × <1000 entries).
|
||||
# For larger batches (>500 rows or >5000 entries), consider
|
||||
# replacing with an Aho-Corasick automaton (e.g., pyahocorasick).
|
||||
matched: list[dict[str, Any]] = []
|
||||
seen_source_match: set = set()
|
||||
|
||||
|
||||
@@ -825,13 +825,19 @@ class InlineCorrectionService:
|
||||
class BulkFindReplaceService:
|
||||
"""Handle bulk find-and-replace on TranslationLanguage entries."""
|
||||
|
||||
MAX_PATTERN_LENGTH = 500
|
||||
|
||||
@staticmethod
|
||||
def _compile_pattern(pattern: str, is_regex: bool) -> re.Pattern:
|
||||
"""Compile a search pattern (regex or plain text)."""
|
||||
import re
|
||||
if is_regex:
|
||||
return re.compile(pattern)
|
||||
return re.compile(re.escape(pattern))
|
||||
if len(pattern) > BulkFindReplaceService.MAX_PATTERN_LENGTH:
|
||||
raise ValueError(
|
||||
f"Pattern too long (max {BulkFindReplaceService.MAX_PATTERN_LENGTH} characters)"
|
||||
)
|
||||
try:
|
||||
return re.compile(pattern) if is_regex else re.compile(re.escape(pattern))
|
||||
except re.error as e:
|
||||
raise ValueError(f"Invalid regex pattern: {e}")
|
||||
|
||||
@staticmethod
|
||||
def _find_matching_entries(
|
||||
|
||||
Reference in New Issue
Block a user