fix: 收紧Bilibili链接解析边界
This commit is contained in:
parent
7522b4c2b2
commit
2d0d8dc4cd
@ -2,10 +2,10 @@ import type { BilibiliVideoReference } from './bilibili-card.types';
|
|||||||
|
|
||||||
const BILIBILI_HOST = 'bilibili.com';
|
const BILIBILI_HOST = 'bilibili.com';
|
||||||
const B23_HOST = 'b23.tv';
|
const B23_HOST = 'b23.tv';
|
||||||
const TRAILING_WRAPPERS = /[\s"'<>,。!?、;:))\]}]+$/u;
|
const TRAILING_WRAPPERS = /[\s"'<>,。!?、;:))\]}】]+$/u;
|
||||||
const LEADING_WRAPPERS = /^[\s"'<>(([{]+/u;
|
const LEADING_WRAPPERS = /^[\s"'<>(([{【]+/u;
|
||||||
const BVID_PATTERN = /(?:^|\/)(BV[0-9A-Za-z]{10,})/;
|
const BVID_PATTERN = /^BV[0-9A-Za-z]{10}$/;
|
||||||
const AID_PATTERN = /(?:^|\/)(?:av|AV)(\d+)(?:$|[/?#])/;
|
const AID_PATTERN = /^(?:av|AV)(\d+)$/;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes QQ card wrappers and punctuation that often stick to copied URLs.
|
* Removes QQ card wrappers and punctuation that often stick to copied URLs.
|
||||||
@ -17,6 +17,10 @@ export function cleanBilibiliUrlCandidate(candidate: string) {
|
|||||||
.replaceAll('&', '&')
|
.replaceAll('&', '&')
|
||||||
.replaceAll('"', '"')
|
.replaceAll('"', '"')
|
||||||
.replaceAll('"', '"')
|
.replaceAll('"', '"')
|
||||||
|
.replaceAll('<', '<')
|
||||||
|
.replaceAll('<', '<')
|
||||||
|
.replaceAll('>', '>')
|
||||||
|
.replaceAll('>', '>')
|
||||||
.replace(LEADING_WRAPPERS, '')
|
.replace(LEADING_WRAPPERS, '')
|
||||||
.replace(TRAILING_WRAPPERS, '')
|
.replace(TRAILING_WRAPPERS, '')
|
||||||
.trim();
|
.trim();
|
||||||
@ -54,18 +58,23 @@ export function parseBilibiliVideoReference(
|
|||||||
if (!isAllowedBilibiliUrl(cleaned)) return null;
|
if (!isAllowedBilibiliUrl(cleaned)) return null;
|
||||||
|
|
||||||
const url = new URL(cleaned);
|
const url = new URL(cleaned);
|
||||||
const probe = `${url.pathname}${url.search}${url.hash}`;
|
const pathSegments = url.pathname.split('/').filter(Boolean);
|
||||||
const bvid = probe.match(BVID_PATTERN)?.[1];
|
const videoSegmentIndex = pathSegments.findIndex(
|
||||||
if (bvid) {
|
(segment) => segment.toLowerCase() === 'video',
|
||||||
|
);
|
||||||
|
if (videoSegmentIndex < 0) return null;
|
||||||
|
|
||||||
|
const videoIdSegment = pathSegments[videoSegmentIndex + 1];
|
||||||
|
if (videoIdSegment && BVID_PATTERN.test(videoIdSegment)) {
|
||||||
return {
|
return {
|
||||||
canonicalVideoId: bvid,
|
canonicalVideoId: videoIdSegment,
|
||||||
kind: 'bvid',
|
kind: 'bvid',
|
||||||
sourceUrl: cleaned,
|
sourceUrl: cleaned,
|
||||||
value: bvid,
|
value: videoIdSegment,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const aid = `${url.pathname}/`.match(AID_PATTERN)?.[1];
|
const aid = videoIdSegment?.match(AID_PATTERN)?.[1];
|
||||||
if (aid) {
|
if (aid) {
|
||||||
return {
|
return {
|
||||||
canonicalVideoId: `av${aid}`,
|
canonicalVideoId: `av${aid}`,
|
||||||
|
|||||||
@ -44,4 +44,33 @@ describe('Bilibili URL parser', () => {
|
|||||||
),
|
),
|
||||||
).toBe('https://www.bilibili.com/video/BV1xx411c7mD?p=1');
|
).toBe('https://www.bilibili.com/video/BV1xx411c7mD?p=1');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('does not parse video ids from query or hash on non-video Bilibili pages', () => {
|
||||||
|
expect(
|
||||||
|
parseBilibiliVideoReference(
|
||||||
|
'https://space.bilibili.com/1?from=/video/BV1xx411c7mD',
|
||||||
|
),
|
||||||
|
).toBeNull();
|
||||||
|
expect(
|
||||||
|
parseBilibiliVideoReference(
|
||||||
|
'https://www.bilibili.com/search?keyword=BV1xx411c7mD',
|
||||||
|
),
|
||||||
|
).toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('rejects malformed BV path segments with extra characters', () => {
|
||||||
|
expect(
|
||||||
|
parseBilibiliVideoReference(
|
||||||
|
'https://www.bilibili.com/video/BV1xx411c7mDextra',
|
||||||
|
),
|
||||||
|
).toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('cleans xml html entities and full-width brackets', () => {
|
||||||
|
expect(
|
||||||
|
cleanBilibiliUrlCandidate(
|
||||||
|
'<【https://www.bilibili.com/video/BV1xx411c7mD】>',
|
||||||
|
),
|
||||||
|
).toBe('https://www.bilibili.com/video/BV1xx411c7mD');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user