mirror of
https://github.com/mozilla/pdf.js.git
synced 2026-08-04 05:17:24 +02:00
Bound the email parts in the autolinker regex
The local part and the domain labels were unbounded, making the search quadratic in the length of a run of characters preceding an "@": scanning the text of a single page could take seconds.
This commit is contained in:
parent
7fc7072f9c
commit
b1f51818ae
@ -220,4 +220,24 @@ describe("autolinker", function () {
|
||||
["john.doe@uni-cityname.tld", "mailto:john.doe@uni-cityname.tld"],
|
||||
]);
|
||||
});
|
||||
|
||||
it("should find emails with the longest parts allowed by the RFCs", function () {
|
||||
const local = "a".repeat(64);
|
||||
const label = "b".repeat(63);
|
||||
testLinks([[`${local}@${label}.com`, `mailto:${local}@${label}.com`]]);
|
||||
});
|
||||
|
||||
it("shouldn't find emails with parts longer than allowed by the RFCs", function () {
|
||||
expect(
|
||||
Autolinker.findLinks(`${"a".repeat(107)}@${"a".repeat(80)}.com`)
|
||||
).toEqual([]);
|
||||
});
|
||||
|
||||
it("should handle a long run of characters before an @ efficiently", function () {
|
||||
const text = `${"a".repeat(50000)}@`;
|
||||
|
||||
const startTime = performance.now();
|
||||
expect(Autolinker.findLinks(text)).toEqual([]);
|
||||
expect(performance.now() - startTime).toBeLessThan(1000);
|
||||
});
|
||||
});
|
||||
|
||||
@ -136,10 +136,13 @@ class Autolinker {
|
||||
static #numericTLDRegex;
|
||||
|
||||
static findLinks(text) {
|
||||
// Regex can be tested and verified at https://regex101.com/r/rXoLiT/2.
|
||||
// Regex can be tested and verified at https://regex101.com/r/riHjvK/1.
|
||||
// The email parts are bounded to keep the scan linear: a local part can't
|
||||
// exceed 64 characters (RFC 5321, section 4.5.3.1.1) and a domain label
|
||||
// can't exceed 63 (RFC 1035, section 2.3.4).
|
||||
this.#regex ??=
|
||||
// eslint-disable-next-line regexp/no-super-linear-backtracking
|
||||
/\b(?:https?:\/\/|mailto:|www\.)(?:[\S--[\p{P}<>]]|\/|[\S--[\[\]]]+[\S--[\p{P}<>]])+|(?=\p{L})[\S--[@\p{Ps}\p{Pe}<>]]+@([\S--[[\p{P}--\-]<>]]+(?:\.[\S--[[\p{P}--\-]<>]]+)+)/gv;
|
||||
/\b(?:https?:\/\/|mailto:|www\.)(?:[\S--[\p{P}<>]]|\/|[\S--[\[\]]]+[\S--[\p{P}<>]])+|(?=\p{L})[\S--[@\p{Ps}\p{Pe}<>]]{1,64}@([\S--[[\p{P}--\-]<>]]{1,63}(?:\.[\S--[[\p{P}--\-]<>]]{1,63})+)/gv;
|
||||
|
||||
const [normalizedText, diffs] = normalize(text, { ignoreDashEOL: true });
|
||||
const matches = normalizedText.matchAll(this.#regex);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user