@neo4j-antora/mark-terms 1.1.2 → 1.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/mark-terms.js +40 -33
  2. package/package.json +1 -1
package/mark-terms.js CHANGED
@@ -5,50 +5,56 @@ module.exports = function (registry) {
5
5
 
6
6
  if (!doc.getAttribute('page-terms-to-mark')) return
7
7
 
8
- let terms = doc.getAttribute('page-terms-to-mark').split(',').map(function (value) {
9
- return value.trim();
10
- })
11
8
 
12
- if (!terms) return
9
+ // escape special characters in the term to mark before using
10
+ function escapeRegExp(str) {
11
+ let escapedStr = str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
12
+ return escapedStr
13
+ }
13
14
 
14
- let markTitles = doc.getAttribute('page-terms-mark-titles')? true : false
15
- let devMode = doc.getAttribute('page-terms-dev-mode')
16
-
17
- let marker = doc.getAttribute('page-terms-marker') || '®'
15
+ // test terms against regexp attacks
16
+ // let terms = doc.getAttribute('page-terms-to-mark')
17
+ let terms = doc.getAttribute('page-terms-to-mark')
18
+ if (!/^[\w\s-,]+?$/.test(terms)) {
19
+ doc.getLogger().error(`mark-terms: invalid terms "${terms}"`)
20
+ return
21
+ }
22
+
23
+ const safeTerms = terms.split(',').map(function (value) {
24
+ return escapeRegExp(value.trim());
25
+ })
26
+
27
+ if (!safeTerms) return
18
28
 
19
29
  // test marker
20
30
  // marker must be a string that starts with & ends with ;
31
+ let marker = doc.getAttribute('page-terms-marker') || '®'
21
32
  if (!/^&[\w\s-]+?;$/.test(marker)) {
22
- doc.getLogger().error(`mark-terms: invalid marker "${marker}"`)
33
+ doc.getLogger().error(`(mark-terms) marker '${marker}' is not an HTML entity`)
23
34
  return
24
35
  }
25
36
 
37
+ let markTitles = doc.getAttribute('page-terms-mark-titles')? true : false
38
+ let devMode = doc.getAttribute('page-terms-dev-mode')
39
+
40
+ const safeMarker = escapeRegExp(marker)
41
+
26
42
  let markAdded = []
27
43
 
28
- terms.forEach(term => {
44
+ safeTerms.forEach(safeTerm => {
29
45
 
30
- // test term
46
+ // test safeTerm
31
47
  // let's reject it if it contains anything other than word characters, spaces, numbers, or hyphens
32
- if (!/^[\w\s-]+$/.test(term)) {
33
- doc.getLogger().error(`mark-terms: invalid term "${term}"`)
48
+ if (!/^[\w\s-]+$/.test(safeTerm)) {
49
+ doc.getLogger().error(`(mark-terms): term '${safeTerm}' is not valid. Terms must only contain letters, numbers, spaces, or hyphens.`)
34
50
  return
35
51
  }
36
52
 
37
- // escape special characters in the term to mark before using in regexp
38
- function escapeRegExp(str) {
39
- let escapedStr = str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
40
- return escapedStr
41
- }
42
-
43
- let re = new RegExp(`(^|\\[|\\s)${escapeRegExp(term)}\\b`)
44
-
45
- let reMarked = new RegExp(`${escapeRegExp(term)} ${escapeRegExp(marker)}`)
46
-
47
53
  doc.findBy().forEach(block => {
48
54
 
49
55
  // if we've already marked ths, don't mark it again
50
56
  // unless testing in dev mode
51
- if ( markAdded.includes(term) && !devMode) return
57
+ if ( markAdded.includes(safeTerm) && !devMode) return
52
58
 
53
59
  // lists
54
60
  if (block.getContext() === 'olist' || block.getContext() === 'ulist') {
@@ -82,7 +88,7 @@ module.exports = function (registry) {
82
88
 
83
89
  // test each line
84
90
  block.lines.forEach((line, i) => {
85
- let reggedLine = testLine(line)
91
+ let reggedLine = testLine(line, i)
86
92
  block.lines[i] = reggedLine
87
93
  })
88
94
 
@@ -90,20 +96,21 @@ module.exports = function (registry) {
90
96
 
91
97
  // test a line of content from a block or a table cell
92
98
  function testLine(line) {
99
+
100
+ const safelyMarkedTerm = safeTerm + safeMarker
93
101
 
94
102
  // return if we've already marked this term
95
- if (markAdded.includes(term) && !devMode) return line
103
+ if (markAdded.includes(safeTerm) && !devMode) return line
96
104
 
97
- // return if this term is already marked
98
- if (reMarked.test(line)) {
99
- markAdded.push(term)
100
- return line
105
+ if (line.includes(safelyMarkedTerm)) {
106
+ markAdded.push(safeTerm)
107
+ return line
101
108
  }
102
109
 
103
110
  // mark the first instance of the term if we find a match
104
- if (re.test(line)) {
105
- markAdded.push(term)
106
- return line.replace(re, '$1' + term + marker)
111
+ if (line.includes(safeTerm)) {
112
+ doc.getLogger().info(`(mark-terms) marked '${safeTerm}'`)
113
+ return line.replace(safeTerm, safelyMarkedTerm)
107
114
  }
108
115
 
109
116
  // we checked but there was no match
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neo4j-antora/mark-terms",
3
- "version": "1.1.2",
3
+ "version": "1.1.3",
4
4
  "description": "Asciidoc extension to mark the first instance of a term on a page, typically with a copyright symbol",
5
5
  "main": "mark-terms.js",
6
6
  "scripts": {