-
Notifications
You must be signed in to change notification settings - Fork 5.5k
add utils regexes list #16745
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add utils regexes list #16745
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,80 @@ | ||||||||||||||||||
| import buildRegExp from "../../common/text/buildRegExp.mjs"; | ||||||||||||||||||
| import pipedream_utils from "../../pipedream_utils.app.mjs"; | ||||||||||||||||||
| export default { | ||||||||||||||||||
| name: "Formatting - [Text] Extract by Regular Expressions List (Regex)", | ||||||||||||||||||
| description: "Find matches for regular expressions. Returns all matched groups with start and end position.", | ||||||||||||||||||
| key: "pipedream_utils-extract-by-regular-expressions-list", | ||||||||||||||||||
| version: "0.0.1", | ||||||||||||||||||
| type: "action", | ||||||||||||||||||
| props: { | ||||||||||||||||||
| pipedream_utils, | ||||||||||||||||||
| input: { | ||||||||||||||||||
| type: "string", | ||||||||||||||||||
| label: "Input", | ||||||||||||||||||
| description: "Text you would like to find a pattern from", | ||||||||||||||||||
| }, | ||||||||||||||||||
| regExpStrings: { | ||||||||||||||||||
| type: "string[]", | ||||||||||||||||||
| label: "Regular Expressions", | ||||||||||||||||||
| description: "An array of [regex strings](https://www.w3schools.com/js/js_regexp.asp) (e.g. `/foo/g`, `/bar/i`)", | ||||||||||||||||||
| }, | ||||||||||||||||||
| }, | ||||||||||||||||||
| methods: { | ||||||||||||||||||
| getAllResults(input) { | ||||||||||||||||||
| const resultMap = {}; | ||||||||||||||||||
| const resultList = []; | ||||||||||||||||||
|
|
||||||||||||||||||
| for (const rStr of this.regExpStrings) { | ||||||||||||||||||
| if (typeof rStr !== "string" || !rStr.length) { | ||||||||||||||||||
| // still push an empty array to preserve order | ||||||||||||||||||
| resultMap[rStr] = []; | ||||||||||||||||||
| resultList.push([]); | ||||||||||||||||||
| continue; | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| const re = rStr.startsWith("/") | ||||||||||||||||||
| ? buildRegExp(rStr, [ | ||||||||||||||||||
| "g", | ||||||||||||||||||
| ]) | ||||||||||||||||||
| : new RegExp(rStr, "g"); | ||||||||||||||||||
|
|
||||||||||||||||||
| const matches = [ | ||||||||||||||||||
| ...input.matchAll(re), | ||||||||||||||||||
| ].map((m) => ({ | ||||||||||||||||||
| match: m[0], | ||||||||||||||||||
| groups: m.groups ?? {}, | ||||||||||||||||||
| startPosition: m.index, | ||||||||||||||||||
| endPosition: m.index + m[0].length, | ||||||||||||||||||
| })); | ||||||||||||||||||
|
|
||||||||||||||||||
| resultMap[rStr] = matches; | ||||||||||||||||||
| resultList.push(matches); | ||||||||||||||||||
| } | ||||||||||||||||||
|
|
||||||||||||||||||
| return { | ||||||||||||||||||
| resultMap, | ||||||||||||||||||
| resultList, | ||||||||||||||||||
| }; | ||||||||||||||||||
| }, | ||||||||||||||||||
| }, | ||||||||||||||||||
| async run({ $ }) { | ||||||||||||||||||
| const { | ||||||||||||||||||
| resultMap, | ||||||||||||||||||
| resultList, | ||||||||||||||||||
| } = this.getAllResults(this.input); | ||||||||||||||||||
|
|
||||||||||||||||||
| const totalMatches = resultList.reduce((sum, arr) => sum + arr.length, 0); | ||||||||||||||||||
|
|
||||||||||||||||||
| $.export( | ||||||||||||||||||
| "$summary", | ||||||||||||||||||
| totalMatches | ||||||||||||||||||
| ? `Found ${totalMatches} matches across ${Object.keys(resultMap).length} patterns` | ||||||||||||||||||
| : "No matches found", | ||||||||||||||||||
| ); | ||||||||||||||||||
|
|
||||||||||||||||||
| return { | ||||||||||||||||||
| map: resultMap, | ||||||||||||||||||
| list: resultList, | ||||||||||||||||||
| }; | ||||||||||||||||||
| }, | ||||||||||||||||||
| }; | ||||||||||||||||||
|
Comment on lines
+1
to
+80
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Verification agent 🧩 Analysis chainConsider adding protection against ReDoS attacks. Regular expressions provided by users could potentially cause Regular Expression Denial of Service (ReDoS) attacks if they contain patterns with catastrophic backtracking. Consider implementing:
🌐 Web query: 💡 Result: Best Practices to Prevent ReDoS Attacks in JavaScriptRegular Expression Denial of Service (ReDoS) vulnerabilities occur when poorly structured regular expressions allow attackers to supply input that causes excessive backtracking. This can hang or crash JavaScript applications, especially in single-threaded Node.js environments[3][4]. Below are the best practices to prevent and mitigate ReDoS attacks in JavaScript: 1. Avoid Vulnerable Patterns
2. Use Bounded Quantifiers and Possessive Patterns
3. Validate and Sanitize Input Used in Regex Construction
4. Limit Input Length
5. Use Proven and Reviewed Patterns
6. Set Timeouts or Monitor Execution
7. Test and Visualize Regex Performance
8. Educate Developers and Review Regular Expressions
Summary Table: Common ReDoS Mitigation Strategies
Key Takeaway: Citations:
I’d like to inspect how 🏁 Script executed: #!/bin/bash
# Locate and display the buildRegExp implementation
fd buildRegExp.mjsLength of output: 75 🏁 Script executed: #!/bin/bash
# Display the contents of buildRegExp to check for sanitization or safety mechanisms
sed -n '1,200p' components/pipedream_utils/common/text/buildRegExp.mjsLength of output: 522 Mitigate ReDoS Risks in User-Supplied Regexes The current implementation in Suggested fixes:
File locations to update:
🤖 Prompt for AI Agents |
||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Consider adding RegExp validation and error handling.
The code handles different regex formats but doesn't protect against invalid regex patterns that might throw exceptions.
const re = rStr.startsWith("/") ? buildRegExp(rStr, [ "g", ]) : new RegExp(rStr, "g"); + + // Add try/catch to handle invalid regex patternsConsider wrapping the RegExp creation in a try/catch block to gracefully handle syntax errors in user-provided regex patterns:
🤖 Prompt for AI Agents