fix: prevent VALUE/MVALUE self-recursion#1019
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
WalkthroughAdds regression tests for issue Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes
Poem
Pre-merge checks and finishing touches✅ Passed checks (5 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (1)
src/formatters/formatter-issue920.test.ts (1)
87-117: Comprehensive regression coverage for the core issue.The four test cases correctly verify that:
- Self-referential input (returning
{{VALUE}}or{{MVALUE}}from prompts) is treated as literal.- Partial matches (e.g.,
prefix {{VALUE}}) do not trigger recursive expansion.The test at lines 100-104 covers multiple
{{VALUE}}occurrences, which is excellent.Optional: Add a test case for multiple MVALUE occurrences
Consider adding a test to verify behavior when multiple
{{MVALUE}}placeholders are present:+ it("handles multiple {{MVALUE}} placeholders independently", async () => { + formatter.setMathResponse("5"); + const result = await formatter.testFormat("A {{MVALUE}} B {{MVALUE}} C"); + expect(result).toBe("A 5 B 5 C"); + });This would document the intended behavior (each occurrence prompts independently) and guard against regressions.
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
src/formatters/formatter-issue920.test.ts(1 hunks)src/formatters/formatter.ts(2 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
src/**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
Source code lives in
src/: core logic underengine/,services/, andutils/; Svelte UI insrc/gui; shared types insrc/types; settings entry insrc/quickAddSettingsTab.ts
Files:
src/formatters/formatter-issue920.test.tssrc/formatters/formatter.ts
src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
src/**/*.{ts,tsx}: Biome enforces tab indentation (width 2), LF endings, and an 80-character line guide; align editor settings
Use camelCase for variables and functions
Prefer type-only imports in TypeScript files
Route logging through theloggerutilities for consistent output
Structure production code so Obsidian dependencies are injected behind interfaces; unit tests target pure logic and swap in adapters ortests/obsidian-stub.ts
Files:
src/formatters/formatter-issue920.test.tssrc/formatters/formatter.ts
src/**/*.{ts,tsx,svelte}
📄 CodeRabbit inference engine (AGENTS.md)
Use PascalCase for classes and Svelte components
Files:
src/formatters/formatter-issue920.test.tssrc/formatters/formatter.ts
🧠 Learnings (1)
📚 Learning: 2025-12-09T21:20:52.425Z
Learnt from: CR
Repo: chhoumann/quickadd PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-09T21:20:52.425Z
Learning: Applies to tests/**/*.{ts,tsx} : Add regression coverage for bug fixes
Applied to files:
src/formatters/formatter-issue920.test.ts
🧬 Code graph analysis (1)
src/formatters/formatter.ts (1)
src/constants.ts (2)
NAME_VALUE_REGEX(71-71)MATH_VALUE_REGEX(91-91)
🪛 ast-grep (0.40.0)
src/formatters/formatter.ts
[warning] 147-147: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(NAME_VALUE_REGEX.source, "gi")
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html
(regexp-from-variable)
[warning] 370-370: Regular expression constructed from variable input detected. This can lead to Regular Expression Denial of Service (ReDoS) attacks if the variable contains malicious patterns. Use libraries like 'recheck' to validate regex safety or use static patterns.
Context: new RegExp(MATH_VALUE_REGEX.source, "gi")
Note: [CWE-1333] Inefficient Regular Expression Complexity [REFERENCES]
- https://owasp.org/www-community/attacks/Regular_expression_Denial_of_Service_-_ReDoS
- https://cwe.mitre.org/data/definitions/1333.html
(regexp-from-variable)
🔇 Additional comments (4)
src/formatters/formatter-issue920.test.ts (1)
7-85: Well-designed test fixture.The
Issue920TestFormatterclass provides clean test isolation by stubbing all abstract methods and exposing configurable prompt responses. This focused approach allows you to test the specific replacement logic without dependencies on the full Obsidian app context.src/formatters/formatter.ts (3)
130-152: Excellent fix for VALUE self-recursion.The implementation correctly prevents infinite loops by:
- Fast-path optimization (line 133): skips work when no placeholders exist.
- Single prompt (line 142): prompts once per formatter run, allowing empty string as valid input.
- Single-pass replacement (line 148): the replacer function ensures all occurrences are replaced in one pass without re-scanning the output, and treats
$in user input literally (not as a special replacement character).The logic preserves programmatic
valueinjection viahasConcreteVariable("value")(line 137), maintaining backward compatibility.
368-385: Correct single-pass implementation for MVALUE.The refactored logic prevents infinite loops by scanning the original
inputstring once and buildingoutputincrementally:
- The regex scans
input(which never changes), not the accumulatedoutput.- The local
lastIndexvariable tracks the copy position ininputfor building segments.- Each
{{MVALUE}}triggers a prompt (line 379), which differs fromVALUEbehavior (prompt once, reuse for all). This appears intentional for supporting independent math calculations at each placeholder.The approach ensures that if a user enters
{{MVALUE}}as input to the math prompt, it won't trigger re-scanning because we're iterating over the original input, not the output being constructed.
148-148: Static analysis warnings are false positives.The ast-grep tool flags lines 148 and 371 for potential ReDoS vulnerabilities. However, both
NAME_VALUE_REGEXandMATH_VALUE_REGEXare constant patterns defined insrc/constants.ts:export const NAME_VALUE_REGEX = new RegExp(/{{NAME}}|{{VALUE}}/i); export const MATH_VALUE_REGEX = new RegExp(/{{MVALUE}}/i);These are simple literal alternations with no user input, complex quantifiers, or backtracking. There is no ReDoS risk here.
Also applies to: 371-371
|
🎉 This PR is included in version 2.9.4 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
|
🚀 Release has been published: v2.9.4 |
Fixes #920
Prevents the formatter from hanging when user input contains
{{value}}/{{mvalue}}by making VALUE/MVALUE replacement non-recursive and single-pass.bun run test/bun run buildpass locallySummary by CodeRabbit
Bug Fixes
Tests
✏️ Tip: You can customize this high-level summary in your review settings.