fix: lack parameters integrity check; typo (#693)

This commit is contained in:
Rongrong 2022-05-15 19:18:37 +08:00 committed by GitHub
parent 71351fd90a
commit c75ee89d58
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 66 additions and 39 deletions

View File

@ -3,31 +3,52 @@ import RouteRecognizer from 'route-recognizer';
function ruleHandler(rule, params, url, html, success, fail) {
const run = () => {
let reaultWithParams;
let resultWithParams;
if (typeof rule.target === 'function') {
const parser = new DOMParser();
const document = parser.parseFromString(html, 'text/html');
try {
reaultWithParams = rule.target(params, url, document);
resultWithParams = rule.target(params, url, document);
} catch (error) {
console.warn(error);
reaultWithParams = '';
resultWithParams = '';
}
} else if (typeof rule.target === 'string') {
reaultWithParams = rule.target;
resultWithParams = rule.target;
}
if (reaultWithParams) {
for (const param in params) {
reaultWithParams = reaultWithParams.replace(`/:${param}`, `/${params[param]}`);
if (resultWithParams) {
const requiredParams = resultWithParams.match(/\/:\w+\??(?=\/|$)/g).map((param) => ({
name: param.slice(2).replace(/\?$/, ''),
optional: param.endsWith('?'),
}));
for (const param of requiredParams) {
if (params[param.name]) {
// successfully matched
const regex = new RegExp(`/:${param.name}\\??(?=/|$)`);
resultWithParams = resultWithParams.replace(regex, `/${params[param.name]}`);
} else if (param.optional) {
// missing optional parameter, drop all following parameters, otherwise the route will be invalid
const regex = new RegExp(`/:${param.name}\\?(/.*)?$`);
resultWithParams = resultWithParams.replace(regex, '');
break;
} else {
// missing necessary parameter, fail
resultWithParams = '';
break;
}
}
// bypassing double-check since `:` maybe a part of parameter value
// if (resultWithParams && resultWithParams.includes(':')) {
// // double-check
// resultWithParams = '';
// }
}
return reaultWithParams;
return resultWithParams;
};
const reaultWithParams = run();
if (reaultWithParams && (!rule.verification || rule.verification(params))) {
success(reaultWithParams);
const resultWithParams = run();
if (resultWithParams && (!rule.verification || rule.verification(params))) {
success(resultWithParams);
} else {
fail();
}
@ -65,35 +86,41 @@ export function getPageRSSHub(data) {
if (rule) {
const recognized = [];
rule.forEach((ru, index) => {
if (ru.source !== undefined) {
if (Object.prototype.toString.call(ru.source) === '[object Array]') {
ru.source.forEach((source) => {
const router = new RouteRecognizer();
router.add([
{
path: source,
handler: index,
},
]);
const result = router.recognize(new URL(url).pathname.replace(/\/$/, ''));
if (result && result[0]) {
recognized.push(result[0]);
}
});
} else if (typeof ru.source === 'string') {
const router = new RouteRecognizer();
router.add([
{
path: ru.source,
handler: index,
},
]);
const result = router.recognize(new URL(url).pathname.replace(/\/$/, ''));
if (result && result[0]) {
recognized.push(result[0]);
const oriSources = Object.prototype.toString.call(ru.source) === '[object Array]' ? ru.source : typeof ru.source === 'string' ? [ru.source] : [];
let sources = [];
// route-recognizer do not support optional segments or partial matching
// thus, we need to manually handle it
// allowing partial matching is necessary, since many rule authors did not mark optional segments
oriSources.forEach((source) => {
// trimming `?` is necessary, since route-recognizer considers it as a part of segment
source = source.replace(/(\/:\w+)\?(?=\/|$)/g, '$1');
sources.push(source);
let tailMatch;
do {
tailMatch = source.match(/\/:\w+$/);
if (tailMatch) {
const tail = tailMatch[0];
source = source.slice(0, source.length - tail.length);
sources.push(source);
}
} while (tailMatch);
});
// deduplicate (some rule authors may already have done similar job)
sources = sources.filter((item, index) => sources.indexOf(item) === index);
// match!
sources.forEach((source) => {
const router = new RouteRecognizer();
router.add([
{
path: source,
handler: index,
},
]);
const result = router.recognize(new URL(url).pathname.replace(/\/$/, ''));
if (result && result[0]) {
recognized.push(result[0]);
}
}
});
});
const result = [];
Promise.all(