From 5dab1976d3536c8fbf92c54fdc6a02ee8bd7657f Mon Sep 17 00:00:00 2001 From: Divlo Date: Mon, 2 Jan 2023 19:45:46 +0100 Subject: [PATCH] feat: validate link in image src --- src/index.js | 37 ++++++++++++++++++++++++++----------- test/basic.test.js | 16 +++++++++++++--- test/fixtures/Invalid.md | 2 ++ test/fixtures/Valid.md | 2 ++ test/fixtures/image.png | Bin 0 -> 95 bytes 5 files changed, 43 insertions(+), 14 deletions(-) create mode 100755 test/fixtures/image.png diff --git a/src/index.js b/src/index.js index 69f7fdf..c417e33 100644 --- a/src/index.js +++ b/src/index.js @@ -56,23 +56,38 @@ const customRule = { filterTokens(params, 'inline', (token) => { token.children.forEach((child) => { const { lineNumber, type, attrs } = child + + /** @type {string | null} */ + let hrefSrc = null + if (type === 'link_open') { attrs.forEach((attr) => { if (attr[0] === 'href') { - const href = attr[1] - const url = new URL(href, pathToFileURL(params.name)) - url.hash = '' - const isRelative = - href.startsWith('./') || - href.startsWith('../') || - !EXTERNAL_PROTOCOLS.has(url.protocol) - if (isRelative && !fs.existsSync(url.pathname)) { - const detail = `Link "${href}" is dead` - addError(onError, lineNumber, detail) - } + hrefSrc = attr[1] } }) } + + if (type === 'image') { + attrs.forEach((attr) => { + if (attr[0] === 'src') { + hrefSrc = attr[1] + } + }) + } + + if (hrefSrc != null) { + const url = new URL(hrefSrc, pathToFileURL(params.name)) + url.hash = '' + const isRelative = + hrefSrc.startsWith('./') || + hrefSrc.startsWith('../') || + !EXTERNAL_PROTOCOLS.has(url.protocol) + if (isRelative && !fs.existsSync(url.pathname)) { + const detail = `Link "${hrefSrc}" is dead` + addError(onError, lineNumber, detail) + } + } }) }) } diff --git a/test/basic.test.js b/test/basic.test.js index 964c6d1..ed46ff6 100644 --- a/test/basic.test.js +++ b/test/basic.test.js @@ -12,13 +12,23 @@ tap.test('ensure we validate correctly', async (t) => { customRules: [relativeLinks] }) t.equal(lintResults['test/fixtures/Valid.md'].length, 0) - t.equal(lintResults['test/fixtures/Invalid.md'].length, 1) + t.equal(lintResults['test/fixtures/Invalid.md'].length, 2) + t.equal( - lintResults['test/fixtures/Invalid.md'][0].ruleDescription, + lintResults['test/fixtures/Invalid.md'][0]?.ruleDescription, 'Relative links should be valid' ) t.equal( - lintResults['test/fixtures/Invalid.md'][0].errorDetail, + lintResults['test/fixtures/Invalid.md'][0]?.errorDetail, 'Link "./basic.test.js" is dead' ) + + t.equal( + lintResults['test/fixtures/Invalid.md'][1]?.ruleDescription, + 'Relative links should be valid' + ) + t.equal( + lintResults['test/fixtures/Invalid.md'][1]?.errorDetail, + 'Link "../image.png" is dead' + ) }) diff --git a/test/fixtures/Invalid.md b/test/fixtures/Invalid.md index b3c1983..08abe73 100644 --- a/test/fixtures/Invalid.md +++ b/test/fixtures/Invalid.md @@ -1,3 +1,5 @@ # Invalid [basic.js](./basic.test.js) + +![Image](../image.png) diff --git a/test/fixtures/Valid.md b/test/fixtures/Valid.md index 45c1015..928b357 100644 --- a/test/fixtures/Valid.md +++ b/test/fixtures/Valid.md @@ -1,3 +1,5 @@ # Valid [basic.js](../basic.test.js) + +![Image](./image.png) diff --git a/test/fixtures/image.png b/test/fixtures/image.png new file mode 100755 index 0000000000000000000000000000000000000000..1914264c08781d1f30ee0b8482bccf44586f2dc1 GIT binary patch literal 95 zcmeAS@N?(olHy`uVBq!ia0vp^j3CU&3?x-=hn)ga%mF?ju0VQumF+E%TuG2$FoVOh l8)-lem#2$k2*>s01R$Gz9%CSj!PC{xWt~$(697H@6ZHT9 literal 0 HcmV?d00001