Show HN: Regolith – Regex library that prevents ReDoS CVEs in TypeScript
21–27 of 27 posts
Re: Show HN: Regolith – Regex library that prevents ReDoS CVEs in TypeScript
#22You provide some performance figures; unfortunately they are caught in an image, no doubt to enable color-coding the results. IMHO that's not ideal, tables should be pure text, even if only for accessibility with screen readers. There are other means to provide guiding highlights, like red and green Unicode code points. GitHub is somewhat unique in its strict policy to remove almost any kind of user-side styling from the READMEs, but providing a "photo snapshot" of parts of the README just to get some colors does not feel like the right solution.
Next thing are the actual figures you provide: those range from 11.822µs (best) to 56.534s (worst). They are displayed as
11.822µs
56.534s
making them look almost like the worst performer took around five times as long as the best performer—until you realize there's a mu in there.I must say that personally I remove this so-called "human-readable" format almost wherever I can because I find it not human-readable at all. To me a good numerical display should try and keep the decimal points on top of each other, avoid too many non-significant digits, use digit grouping, and, crucially, use a single unit throughout. With those constraints, the two figures become
11.8µs
56,534,000.0µs
which incidentally obviates much of the need to color code anything. One could discuss what unit—ns, µs, ms, s—is the most appropriate in the given context but, generally, I feel that big numbers should stand out as having many digits.Nobody will pick this up because it's much too elaborate and idiosyncratic for this conformist world, but I just love the 'Japanese' way of formatting where you do digit grouping with the SI prefixes, so one hundred and twenty-five meters is 125m, but one thousand one hundred and twenty-five meters doesn't become 1,125m, nor is it 1.125km, but rather 1k125m (preferrably with a thin space as in 1k_125m—imagine a thin non-breakable space there that HN wouldn't let me render).
1G 255M 368k 799B, what's not to like?
Re: Show HN: Regolith – Regex library that prevents ReDoS CVEs in TypeScript
#23example from blog:
import { createRegExp, exactly, wordChar, oneOrMore, anyOf, } from "magic-regexp";
const regExp = createRegExp(
exactly("http")
.and(exactly("s").optionally())
.and("://")
.optionally()
.and(exactly("www.").optionally())
.and(oneOrMore(wordChar))
.and(exactly("."))
.and(anyOf("com", "org", "io")),
["g", "m", "i"]
);console.log(regExp);
/(https?:\/\/)?(www\.)?\w+\.(com|org|io)/gmi
Re: Show HN: Regolith – Regex library that prevents ReDoS CVEs in TypeScript
#24> Regolith attempts to be a drop-in replacement for RegExp and requires minimal (to no) changes to be used instead vs > Since Regolith uses Rust bindings to implement the Rust Regex library to achieve linear time worst case, this means that backreferences and look-around aren't available in Regolith either. Obviously it cannot be a drop-in replacement if the regex dialect differs. That it has a compatible API is not…
Thanks for the feedback! Yea, you're totally right. I'll update the docs to reflect this. > why not just wrap vanilla JS regex, rejecting patterns including them? Yea! I was thinking about this too actually. And this would solve the problem of being server side only. I'm thinking about making a new version to do just this. For a pattern rejecting wrapper, how would you want it to communicate that an unsafe pattern ha…
Server-side?
You should look into how you compile your rust into wasm
Re: Show HN: Regolith – Regex library that prevents ReDoS CVEs in TypeScript
#25Re: Show HN: Regolith – Regex library that prevents ReDoS CVEs in TypeScript
#26> Regolith attempts to be a drop-in replacement for RegExp and requires minimal (to no) changes to be used instead vs > Since Regolith uses Rust bindings to implement the Rust Regex library to achieve linear time worst case, this means that backreferences and look-around aren't available in Regolith either. Obviously it cannot be a drop-in replacement if the regex dialect differs. That it has a compatible API is not…
Totally agree -- those are two incredibly useful features of regex[1][2] that are often effectively irreplaceable. I could see this being a straightforward tradeoff for applications that know for sure they don't need complex regexes but still must accept patterns written by the client for some reason(?), but otherwise this seems like a hell of a way to go to replace a `timeout` wrapper. This paragraph in particular s…
It's likely a shock because you over-estimate their utility:
> those are two incredibly useful features of regex that are often effectively irreplaceable.
Tons of people are using the `regex` crate in the Rust ecosystem. Tons use RE2 with C++. And tons use the standard library `regexp` package with Go. If all of these libraries were lacking actually "irreplaceable" features, I don't think they would be so widely used. So I think, empirically, you overstate things here.
They are of course undeniably useful features, and you don't need them to write complex regexes. The fact of the matter is that a lot (not all) of uses of lookaround or backreferences can be replaced with either careful use of capture groups or a second regex.
The place where one might really feel the absence of these regex features is when regexes are used as the interface to something.
Besides, if you need those extra features in the Rust ecosystem, you can just use `fancy-regex`[1]. It's built on top of the `regex` crate.
Re: Show HN: Regolith – Regex library that prevents ReDoS CVEs in TypeScript
#27Earlier quoted context omitted.
> Another thought: since backreferences and lookaround are the features in JS regexes which _cause_ ReDOS, This is incorrect. Other features can cause ReDOS. The other problematic features have linear time algorithms that could be used, but generally are not used (i assume for better average case performance)
Right. An example regex that can be slow is CSV parsing [1]: .*,.*,.*,.*,.* etc. I believe a timeout is a better (simpler) solution than to try to prevent 'bad' patterns. I use this approach in my own (tiny, ~400 lines) regex library [2]. I use a limit at most ~100 operations per input byte. So, without measuring wall clock time, which can be inaccurate. [1]: https://stackoverflow.com/questions/2667015/is-regex-too-s…