securemark 0.300.5 → 0.300.7

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.300.7
4
+
5
+ - Refactoring.
6
+
7
+ ## 0.300.6
8
+
9
+ - Refactoring.
10
+
3
11
  ## 0.300.5
4
12
 
5
13
  - Refactoring.
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- /*! securemark v0.300.5 https://github.com/falsandtru/securemark | (c) 2017, falsandtru | UNLICENSED License */
1
+ /*! securemark v0.300.7 https://github.com/falsandtru/securemark | (c) 2017, falsandtru | UNLICENSED License */
2
2
  (function webpackUniversalModuleDefinition(root, factory) {
3
3
  if(typeof exports === 'object' && typeof module === 'object')
4
4
  module.exports = factory(require("Prism"), require("DOMPurify"));
@@ -6414,7 +6414,6 @@ exports.input = input;
6414
6414
  class Input extends parser_1.Input {
6415
6415
  constructor(options = {}, source) {
6416
6416
  super(options);
6417
- this.recursion = new RecursionCounter(2);
6418
6417
  const {
6419
6418
  segment,
6420
6419
  header,
@@ -6449,23 +6448,6 @@ class Input extends parser_1.Input {
6449
6448
  }
6450
6449
  }
6451
6450
  exports.Input = Input;
6452
- class RecursionCounter {
6453
- constructor(limit) {
6454
- this.limit = limit;
6455
- this.stack = [];
6456
- this.index = 0;
6457
- }
6458
- add(depth) {
6459
- const {
6460
- stack
6461
- } = this;
6462
- for (; this.index > 0 && stack[this.index - 1] >= depth; --this.index);
6463
- // 内側から数えるので無効化処理できずエラーを投げるしかない。
6464
- if (this.index === this.limit) return new Error(`Too much recursion`);
6465
- stack[this.index] = depth;
6466
- ++this.index;
6467
- }
6468
- }
6469
6451
 
6470
6452
  /***/ },
6471
6453
 
@@ -6729,9 +6711,7 @@ exports.annotation = (0, combinator_1.lazy)(() => (0, combinator_1.constraint)(1
6729
6711
  const {
6730
6712
  position,
6731
6713
  linebreak,
6732
- range,
6733
- recursion,
6734
- resources
6714
+ range
6735
6715
  } = input;
6736
6716
  if (linebreak !== 0 || nodes.length === 0 || lead === 0 || follow % 2 === 0) {
6737
6717
  nodes.unshift(new parser_1.Node('('));
@@ -6740,14 +6720,20 @@ exports.annotation = (0, combinator_1.lazy)(() => (0, combinator_1.constraint)(1
6740
6720
  class: (0, bracket_1.bracketname)(input, 1, 1)
6741
6721
  }, (0, dom_1.defrag)((0, util_1.unwrap)(nodes))))]);
6742
6722
  }
6743
- output.error ??= recursion.add(resources?.recursions[2 /* Recursion.inline */] ?? resources?.recursions.at(-1));
6744
6723
  input.position += 1;
6745
6724
  const el = (0, dom_1.html)('sup', {
6746
6725
  class: 'annotation'
6747
6726
  }, [(0, dom_1.html)('span', (0, dom_1.defrag)((0, util_1.unwrap)((0, visibility_1.trimBlankNodeEnd)(nodes))))]);
6748
6727
  for (let list = output.annotations.at(-1), node = list.last, pos = position - range, i = 0;; node = node.prev, ++i) {
6749
- if (node && node.position > pos) continue;
6750
- i === list.length ? list.unshift(new parser_1.Node(el, pos)) : list.insert(new parser_1.Node(el, pos), node?.next);
6728
+ if (node && node.position > pos) {
6729
+ if (~node.flags & 2 /* Node.Flag.nested */) continue;
6730
+ return new parser_1.List([new parser_1.Node((0, dom_1.define)(el.firstElementChild, {
6731
+ class: 'invalid',
6732
+ ...(0, util_1.invalid)('annotation', 'syntax', 'Recursions must be two or fewer')
6733
+ }))]);
6734
+ }
6735
+ const flag = i === 0 ? 0 /* Node.Flag.none */ : 2 /* Node.Flag.nested */;
6736
+ i === list.length ? list.unshift(new parser_1.Node(el, pos, flag)) : list.insert(new parser_1.Node(el, pos, flag), node?.next);
6751
6737
  break;
6752
6738
  }
6753
6739
  return new parser_1.List([new parser_1.Node(el)]);
@@ -8685,6 +8671,7 @@ function repeat(opener, after, closer, recursion, parser, cons, termination = (n
8685
8671
  input.position += closer.length;
8686
8672
  const pos = input.position;
8687
8673
  m.follow = m.follow > 0 ? m.follow : countFollows(source, pos, closer, lead / opener.length | 0);
8674
+ input.range = input.position - m.position - m.i + opener.length;
8688
8675
  output.push(cons(output.pop(), input, output, lead, m.follow));
8689
8676
  if (input.position > pos) {
8690
8677
  const advance = input.position - pos;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "securemark",
3
- "version": "0.300.5",
3
+ "version": "0.300.7",
4
4
  "description": "Secure markdown renderer working on browsers for user input data.",
5
5
  "private": false,
6
6
  "homepage": "https://github.com/falsandtru/securemark",
@@ -314,33 +314,6 @@ describe('Unit: api/parse', () => {
314
314
  assert.deepStrictEqual(
315
315
  [...run(parse(`${'{ '.repeat(101)}0`)).children].map(el => el.tagName),
316
316
  ['H1', 'PRE', 'OL']);
317
- assert.deepStrictEqual(
318
- [...run(parse(`${'(('.repeat(2)}0${'))'.repeat(2)}`)).children].map(el => el.tagName),
319
- ['P', 'OL', 'OL']);
320
- assert.deepStrictEqual(
321
- [...run(parse(`${'(('.repeat(3)}0${'))'.repeat(3)}`)).children].map(el => el.tagName),
322
- ['H1', 'PRE', 'OL']);
323
- assert.deepStrictEqual(
324
- [...run(parse(`(${'(('.repeat(2)}0${'))'.repeat(2)}`)).children].map(el => el.tagName),
325
- ['P', 'OL', 'OL']);
326
- assert.deepStrictEqual(
327
- [...run(parse(`(${'(('.repeat(3)}0${'))'.repeat(3)}`)).children].map(el => el.tagName),
328
- ['H1', 'PRE', 'OL']);
329
- assert.deepStrictEqual(
330
- [...run(parse(`${'(('.repeat(2)}0${'))'.repeat(2)}${'(('.repeat(2)}0${'))'.repeat(2)}`)).children].map(el => el.tagName),
331
- ['P', 'OL', 'OL']);
332
- assert.deepStrictEqual(
333
- [...run(parse(`${'(('.repeat(2)}0${'))'.repeat(2)}${'(('.repeat(3)}0${'))'.repeat(3)}`)).children].map(el => el.tagName),
334
- ['H1', 'PRE', 'OL']);
335
- assert.deepStrictEqual(
336
- [...run(parse(`${'(('.repeat(2)}0${'))'.repeat(2)}${'(('.repeat(9)}0${'))'.repeat(2)}`)).children].map(el => el.tagName),
337
- ['P', 'OL', 'OL']);
338
- assert.deepStrictEqual(
339
- [...run(parse(`${'(('.repeat(2)}0${'))'.repeat(2)}${'(('.repeat(9)}0${'))'.repeat(3)}`)).children].map(el => el.tagName),
340
- ['H1', 'PRE', 'OL']);
341
- assert.deepStrictEqual(
342
- [...run(parse(`${'(('.repeat(3)}0))((1))))))`)).children].map(el => el.tagName),
343
- ['H1', 'PRE', 'OL']);
344
317
  });
345
318
 
346
319
  it('recovery', () => {
@@ -159,6 +159,7 @@ export class Node<T> implements List.Node {
159
159
  export namespace Node {
160
160
  export const enum Flag {
161
161
  none,
162
- blank,
162
+ blank = 1 << 0,
163
+ nested = 1 << 1,
163
164
  }
164
165
  }
@@ -56,7 +56,6 @@ export class Input<M extends object = object> extends Ipt<M> {
56
56
  public header: boolean;
57
57
  public local: boolean;
58
58
  public whitespace: boolean;
59
- public recursion = new RecursionCounter(2);
60
59
  public readonly host?: URL;
61
60
  public readonly url?: URL;
62
61
  public id?: string;
@@ -72,23 +71,6 @@ export class Input<M extends object = object> extends Ipt<M> {
72
71
  }
73
72
  export type Options = Partial<Input>;
74
73
 
75
- class RecursionCounter {
76
- constructor(
77
- private readonly limit: number,
78
- ) {
79
- }
80
- private readonly stack: number[] = [];
81
- private index = 0;
82
- public add(depth: number): Error | undefined {
83
- const { stack } = this
84
- for (; this.index > 0 && stack[this.index - 1] >= depth; --this.index);
85
- // 内側から数えるので無効化処理できずエラーを投げるしかない。
86
- if (this.index === this.limit) return new Error(`Too much recursion`);
87
- stack[this.index] = depth;
88
- ++this.index;
89
- }
90
- }
91
-
92
74
  export const enum Segment {
93
75
  unknown = 0,
94
76
  read = 0,
@@ -62,6 +62,33 @@ describe('Unit: parser/inline/annotation', () => {
62
62
  assert.deepStrictEqual(inspect(parser, input('(((a)))')), [['<sup class="annotation"><span><span class="paren">(a)</span></span></sup>'], '']);
63
63
  assert.deepStrictEqual(inspect(parser, input('((((a))))')), [['<sup class="annotation"><span><sup class="annotation"><span>a</span></sup></span></sup>'], '']);
64
64
  assert.deepStrictEqual(inspect(parser, input('(([[a]]))')), [['<sup class="annotation"><span><sup class="reference"><span>a</span></sup></span></sup>'], '']);
65
+ assert.deepStrictEqual(
66
+ inspect(parser, input(`${'(('.repeat(2)}0${'))'.repeat(2)}`)),
67
+ [['<sup class="annotation"><span><sup class="annotation"><span>0</span></sup></span></sup>'], '']);
68
+ assert.deepStrictEqual(
69
+ inspect(parser, input(`${'(('.repeat(3)}0${'))'.repeat(3)}`)),
70
+ [['<span class="invalid"><sup class="annotation"><span><sup class="annotation"><span>0</span></sup></span></sup></span>'], '']);
71
+ assert.deepStrictEqual(
72
+ inspect(parser, input(`(${'(('.repeat(2)}0${'))'.repeat(2)}`)),
73
+ [['<span class="paren">(<sup class="annotation"><span><sup class="annotation"><span>0</span></sup></span></sup></span>'], '']);
74
+ assert.deepStrictEqual(
75
+ inspect(parser, input(`(${'(('.repeat(3)}0${'))'.repeat(3)}`)),
76
+ [['<span class="paren">(<span class="invalid"><sup class="annotation"><span><sup class="annotation"><span>0</span></sup></span></sup></span></span>'], '']);
77
+ assert.deepStrictEqual(
78
+ inspect(parser, input(`${'(('.repeat(2)}0${'))'.repeat(2)}${'(('.repeat(2)}0${'))'.repeat(2)}`)),
79
+ [['<sup class="annotation"><span><sup class="annotation"><span>0</span></sup></span></sup>', '<sup class="annotation"><span><sup class="annotation"><span>0</span></sup></span></sup>'], '']);
80
+ assert.deepStrictEqual(
81
+ inspect(parser, input(`${'(('.repeat(2)}0${'))'.repeat(2)}${'(('.repeat(3)}0${'))'.repeat(2)}`)),
82
+ [['<sup class="annotation"><span><sup class="annotation"><span>0</span></sup></span></sup>', '<span class="paren">(<span class="paren">(<sup class="annotation"><span><sup class="annotation"><span>0</span></sup></span></sup></span></span>'], '']);
83
+ assert.deepStrictEqual(
84
+ inspect(parser, input(`${'(('.repeat(2)}0${'))'.repeat(2)}${'(('.repeat(3)}0${'))'.repeat(3)}`)),
85
+ [['<sup class="annotation"><span><sup class="annotation"><span>0</span></sup></span></sup>', '<span class="invalid"><sup class="annotation"><span><sup class="annotation"><span>0</span></sup></span></sup></span>'], '']);
86
+ assert.deepStrictEqual(
87
+ inspect(parser, input(`${'(('.repeat(3)}0))((1))))))`)),
88
+ [['<span class="invalid"><sup class="annotation"><span><sup class="annotation"><span>0</span></sup><sup class="annotation"><span>1</span></sup></span></sup></span>'], '']);
89
+ assert.deepStrictEqual(
90
+ inspect(parser, input(`${'(0'.repeat(4)}((0${'))'.repeat(3)}${'(('.repeat(2)}0${'))'.repeat(2)}`)),
91
+ [['<span class="paren">(0<span class="paren">(0<span class="paren">(0<span class="paren">(0<sup class="annotation"><span>0</span></sup>)</span>)</span>)</span>)</span>', '<sup class="annotation"><span><sup class="annotation"><span>0</span></sup></span></sup>'], '']);
65
92
  });
66
93
 
67
94
  });
@@ -6,8 +6,8 @@ import { inline } from '../inline';
6
6
  import { bracketname } from './bracket';
7
7
  import { repeat } from '../repeat';
8
8
  import { beforeNonblank, trimBlankNodeEnd } from '../visibility';
9
- import { unwrap } from '../util';
10
- import { html, defrag } from 'typed-dom/dom';
9
+ import { unwrap, invalid } from '../util';
10
+ import { html, define, defrag } from 'typed-dom/dom';
11
11
 
12
12
  // シグネチャ等生成のために構文木のツリーウォークを再帰的に行い指数計算量にならないよう
13
13
  // 動的計画法を適用するか再帰数を制限する必要がある。
@@ -32,7 +32,7 @@ export const annotation: AnnotationParser = lazy(() => constraint(State.annotati
32
32
  ([, bs], _, output) => output.import(bs),
33
33
  ([, bs], _, output) => bs && output.import(bs.push(new Node(Command.Cancel)))))),
34
34
  (nodes, input, output, lead, follow) => {
35
- const { position, linebreak, range, recursion, resources } = input;
35
+ const { position, linebreak, range } = input;
36
36
  if (linebreak !== 0 || nodes.length === 0 || lead === 0 || follow % 2 === 0) {
37
37
  nodes.unshift(new Node('('));
38
38
  nodes.push(new Node(')'));
@@ -40,16 +40,25 @@ export const annotation: AnnotationParser = lazy(() => constraint(State.annotati
40
40
  new Node(html('span', { class: bracketname(input, 1, 1) }, defrag(unwrap(nodes))))
41
41
  ]);
42
42
  }
43
- output.error ??= recursion.add(resources?.recursions[Recursion.inline] ?? resources?.recursions.at(-1));
44
43
  input.position += 1;
45
44
  const el = html('sup', { class: 'annotation' }, [
46
45
  html('span', defrag(unwrap(trimBlankNodeEnd(nodes))))
47
46
  ]);
48
47
  for (let list = output.annotations.at(-1)!, node = list.last, pos = position - range, i = 0; ; node = node!.prev, ++i) {
49
- if (node && node.position > pos) continue;
48
+ if (node && node.position > pos) {
49
+ if (~node.flags & Node.Flag.nested) continue;
50
+ return new List([
51
+ new Node(define(el.firstElementChild as HTMLElement,
52
+ {
53
+ class: 'invalid',
54
+ ...invalid('annotation', 'syntax', 'Recursions must be two or fewer')
55
+ }))
56
+ ]);
57
+ }
58
+ const flag = i === 0 ? Node.Flag.none : Node.Flag.nested;
50
59
  i === list.length
51
- ? list.unshift(new Node(el, pos))
52
- : list.insert(new Node(el, pos), node?.next);
60
+ ? list.unshift(new Node(el, pos, flag))
61
+ : list.insert(new Node(el, pos, flag), node?.next);
53
62
  break;
54
63
  }
55
64
  return new List([new Node(el)]);
@@ -93,6 +93,7 @@ export function repeat<T extends HTMLElement | string>(
93
93
  input.position += closer.length;
94
94
  const pos = input.position;
95
95
  m.follow = m.follow > 0 ? m.follow : countFollows(source, pos, closer, lead / opener.length | 0);
96
+ input.range = input.position - m.position - m.i + opener.length;
96
97
  output.push(cons(output.pop(), input, output, lead, m.follow));
97
98
  if (input.position > pos) {
98
99
  const advance = input.position - pos;