1
0
Fork 0
mirror of https://github.com/mozilla/pdf.js.git synced 2025-04-23 16:48:08 +02:00

Make util.scand a bit more flexible with dates which don't match the given format (bug 1910431)

This commit is contained in:
Calixte Denizet 2024-10-27 19:19:06 +01:00
parent bde36f28be
commit 230d7f9229
3 changed files with 108 additions and 110 deletions

View file

@ -38,7 +38,6 @@ class AForm {
"m/d/yy HH:MM",
];
this._timeFormats = ["HH:MM", "h:MM tt", "HH:MM:ss", "h:MM:ss tt"];
this._dateActionsCache = new Map();
// The e-mail address regex below originates from:
// https://html.spec.whatwg.org/multipage/input.html#valid-e-mail-address
@ -53,120 +52,20 @@ class AForm {
return event.target ? `[ ${event.target.name} ]` : "";
}
_tryToGuessDate(cFormat, cDate) {
// We use the format to know the order of day, month, year, ...
let actions = this._dateActionsCache.get(cFormat);
if (!actions) {
actions = [];
this._dateActionsCache.set(cFormat, actions);
cFormat.replaceAll(
/(d+)|(m+)|(y+)|(H+)|(M+)|(s+)/g,
function (match, d, m, y, H, M, s) {
if (d) {
actions.push((n, date) => {
if (n >= 1 && n <= 31) {
date.setDate(n);
return true;
}
return false;
});
} else if (m) {
actions.push((n, date) => {
if (n >= 1 && n <= 12) {
date.setMonth(n - 1);
return true;
}
return false;
});
} else if (y) {
actions.push((n, date) => {
if (n < 50) {
n += 2000;
} else if (n < 100) {
n += 1900;
}
date.setYear(n);
return true;
});
} else if (H) {
actions.push((n, date) => {
if (n >= 0 && n <= 23) {
date.setHours(n);
return true;
}
return false;
});
} else if (M) {
actions.push((n, date) => {
if (n >= 0 && n <= 59) {
date.setMinutes(n);
return true;
}
return false;
});
} else if (s) {
actions.push((n, date) => {
if (n >= 0 && n <= 59) {
date.setSeconds(n);
return true;
}
return false;
});
}
return "";
}
);
}
const number = /\d+/g;
let i = 0;
let array;
const date = new Date();
while ((array = number.exec(cDate)) !== null) {
if (i < actions.length) {
if (!actions[i++](parseInt(array[0]), date)) {
return null;
}
} else {
break;
}
}
if (i === 0) {
return null;
}
return date;
}
_parseDate(cFormat, cDate, strict = false) {
let date = null;
try {
date = this._util.scand(cFormat, cDate);
date = this._util._scand(cFormat, cDate, strict);
} catch {}
if (!date) {
if (strict) {
return null;
}
let format = cFormat;
if (/mm(?!m)/.test(format)) {
format = format.replace("mm", "m");
}
if (/dd(?!d)/.test(format)) {
format = format.replace("dd", "d");
}
try {
date = this._util.scand(format, cDate);
} catch {}
if (date) {
return date;
}
if (!date) {
date = Date.parse(cDate);
date = isNaN(date)
? this._tryToGuessDate(cFormat, cDate)
: new Date(date);
if (strict) {
return null;
}
return date;
date = Date.parse(cDate);
return isNaN(date) ? null : new Date(date);
}
AFMergeChange(event = globalThis.event) {

View file

@ -16,6 +16,8 @@
import { PDFObject } from "./pdf_object.js";
class Util extends PDFObject {
#dateActionsCache = null;
constructor(data) {
super(data);
@ -338,7 +340,98 @@ class Util extends PDFObject {
return buf.join("");
}
#tryToGuessDate(cFormat, cDate) {
// We use the format to know the order of day, month, year, ...
let actions = (this.#dateActionsCache ||= new Map()).get(cFormat);
if (!actions) {
actions = [];
this.#dateActionsCache.set(cFormat, actions);
cFormat.replaceAll(
/(d+)|(m+)|(y+)|(H+)|(M+)|(s+)/g,
function (match, d, m, y, H, M, s) {
if (d) {
actions.push((n, date) => {
if (n >= 1 && n <= 31) {
date.setDate(n);
return true;
}
return false;
});
} else if (m) {
actions.push((n, date) => {
if (n >= 1 && n <= 12) {
date.setMonth(n - 1);
return true;
}
return false;
});
} else if (y) {
actions.push((n, date) => {
if (n < 50) {
n += 2000;
} else if (n < 100) {
n += 1900;
}
date.setYear(n);
return true;
});
} else if (H) {
actions.push((n, date) => {
if (n >= 0 && n <= 23) {
date.setHours(n);
return true;
}
return false;
});
} else if (M) {
actions.push((n, date) => {
if (n >= 0 && n <= 59) {
date.setMinutes(n);
return true;
}
return false;
});
} else if (s) {
actions.push((n, date) => {
if (n >= 0 && n <= 59) {
date.setSeconds(n);
return true;
}
return false;
});
}
return "";
}
);
}
const number = /\d+/g;
let i = 0;
let array;
const date = new Date(0);
while ((array = number.exec(cDate)) !== null) {
if (i < actions.length) {
if (!actions[i++](parseInt(array[0]), date)) {
return null;
}
} else {
break;
}
}
if (i === 0) {
return null;
}
return date;
}
scand(cFormat, cDate) {
return this._scand(cFormat, cDate);
}
_scand(cFormat, cDate, strict = false) {
if (typeof cDate !== "string") {
return new Date(cDate);
}
@ -508,7 +601,7 @@ class Util extends PDFObject {
const matches = new RegExp(`^${re}$`, "g").exec(cDate);
if (!matches || matches.length !== actions.length + 1) {
return null;
return strict ? null : this.#tryToGuessDate(cFormat, cDate);
}
const data = {