securemark 0.295.4 → 0.295.5

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,9 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.295.5
4
+
5
+ - Refactoring.
6
+
3
7
  ## 0.295.4
4
8
 
5
9
  - Refactoring.
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- /*! securemark v0.295.4 https://github.com/falsandtru/securemark | (c) 2017, falsandtru | UNLICENSED License */
1
+ /*! securemark v0.295.5 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"));
@@ -6630,7 +6630,6 @@ const s1 = (0, combinator_1.lazy)(() => (0, combinator_1.surround)((0, source_1.
6630
6630
  } else if (source[position] !== '{') {
6631
6631
  (0, combinator_1.setBacktrack)(context, 2 | 64 /* Backtrack.link */, head);
6632
6632
  } else {
6633
- context.state ^= 8 /* State.link */;
6634
6633
  if (!(0, combinator_1.isBacktrack)(context, 1 | 64 /* Backtrack.link */) && !(0, link_1.textlink)({
6635
6634
  context
6636
6635
  })) {
@@ -6638,7 +6637,6 @@ const s1 = (0, combinator_1.lazy)(() => (0, combinator_1.surround)((0, source_1.
6638
6637
  }
6639
6638
  context.position = position;
6640
6639
  context.range = range;
6641
- context.state ^= 8 /* State.link */;
6642
6640
  }
6643
6641
  }
6644
6642
  return as.import(bs).import(cs);
@@ -6907,19 +6905,14 @@ const dom_1 = __webpack_require__(394);
6907
6905
  exports.index = (0, combinator_1.lazy)(() => (0, combinator_1.constraint)(32 /* State.index */, (0, combinator_1.fmap)((0, indexee_1.indexee)((0, combinator_1.surround)((0, source_1.str)('[#'), (0, combinator_1.precedence)(1, (0, combinator_1.state)(251 /* State.linkers */, (0, visibility_1.tightStart)((0, combinator_1.some)((0, combinator_1.inits)([inline_1.inline, exports.signature]), ']', [[']', 1]])))), (0, source_1.str)(']'), false, [3 | 4 /* Backtrack.common */], ([, bs], context) => context.linebreak === 0 && (0, visibility_1.trimBlankNodeEnd)(bs).length > 0 ? new parser_1.List([new parser_1.Node((0, dom_1.html)('a', {
6908
6906
  'data-index': dataindex(bs)
6909
6907
  }, (0, dom_1.defrag)((0, util_1.unwrap)(bs))))]) : undefined, undefined)), ns => {
6910
- if (ns.length === 1) {
6911
- const el = ns.head.value;
6912
- return new parser_1.List([new parser_1.Node((0, dom_1.define)(el, {
6913
- id: el.id ? null : undefined,
6914
- class: 'index',
6915
- href: el.id ? `#${el.id}` : undefined
6916
- }))]);
6917
- } else {
6918
- ns.pop();
6919
- return ns;
6920
- }
6908
+ const el = ns.head.value;
6909
+ return new parser_1.List([new parser_1.Node((0, dom_1.define)(el, {
6910
+ id: el.id ? null : undefined,
6911
+ class: 'index',
6912
+ href: el.id ? `#${el.id}` : undefined
6913
+ }))]);
6921
6914
  })));
6922
- exports.signature = (0, combinator_1.lazy)(() => (0, combinator_1.validate)('|', (0, combinator_1.surround)((0, source_1.str)(/\|(?!\\?\s)/y), (0, combinator_1.some)((0, combinator_1.union)([htmlentity_1.unsafehtmlentity, (0, combinator_1.some)(source_1.txt, /(?:[$"`\[\](){}<>()[]{}|])/y)]), ']'), /(?=])/y, false, [3 | 16 /* Backtrack.escapable */], ([, ns], context) => {
6915
+ exports.signature = (0, combinator_1.lazy)(() => (0, combinator_1.validate)('|', (0, combinator_1.surround)((0, source_1.str)(/\|(?!\\?\s)/y), (0, combinator_1.precedence)(9, (0, combinator_1.some)((0, combinator_1.union)([htmlentity_1.unsafehtmlentity, (0, combinator_1.some)(source_1.txt, /(?:[$"`\[\](){}<>()[]{}|])/y)]), ']')), /(?=])/y, false, [3 | 16 /* Backtrack.escapable */], ([, ns], context) => {
6923
6916
  const index = (0, indexee_1.identity)('index', undefined, ns.foldl((acc, {
6924
6917
  value
6925
6918
  }) => acc + value, ''))?.slice(7);
@@ -7374,13 +7367,13 @@ const optspec = {
7374
7367
  rel: ['nofollow']
7375
7368
  };
7376
7369
  Object.setPrototypeOf(optspec, null);
7377
- exports.textlink = (0, combinator_1.lazy)(() => (0, combinator_1.constraint)(8 /* State.link */, (0, combinator_1.precedence)(1, (0, combinator_1.state)(251 /* State.linkers */, (0, combinator_1.bind)((0, combinator_1.subsequence)([(0, combinator_1.dup)((0, combinator_1.surround)('[', (0, visibility_1.trimBlankStart)((0, combinator_1.some)((0, combinator_1.union)([inline_1.inline]), ']', [[']', 1]])), ']', true, [3 | 4 /* Backtrack.common */ | 64 /* Backtrack.link */, 2 | 32 /* Backtrack.ruby */], ([, ns = new parser_1.List()], context) => {
7370
+ exports.textlink = (0, combinator_1.lazy)(() => (0, combinator_1.bind)((0, combinator_1.subsequence)([(0, combinator_1.constraint)(8 /* State.link */, (0, combinator_1.state)(251 /* State.linkers */, (0, combinator_1.dup)((0, combinator_1.surround)('[', (0, combinator_1.precedence)(1, (0, visibility_1.trimBlankStart)((0, combinator_1.some)((0, combinator_1.union)([inline_1.inline]), ']', [[']', 1]]))), ']', true, [3 | 4 /* Backtrack.common */ | 64 /* Backtrack.link */, 2 | 32 /* Backtrack.ruby */], ([, ns = new parser_1.List()], context) => {
7378
7371
  if (context.linebreak !== 0) {
7379
7372
  const head = context.position - context.range;
7380
7373
  return void (0, combinator_1.setBacktrack)(context, 2 | 64 /* Backtrack.link */ | 32 /* Backtrack.ruby */, head);
7381
7374
  }
7382
7375
  return ns.push(new parser_1.Node("\u001F" /* Command.Separator */)) && ns;
7383
- })),
7376
+ })))),
7384
7377
  // `{ `と`{`で個別にバックトラックが発生し+1nされる。
7385
7378
  // 自己再帰的にパースしてもオプションの不要なパースによる計算量の増加により相殺される。
7386
7379
  (0, combinator_1.dup)((0, combinator_1.surround)(/{(?![{}])/y, (0, combinator_1.precedence)(9, (0, combinator_1.inits)([exports.uri, (0, combinator_1.some)(exports.option)])), / ?}/y, false, [], undefined, ([as, bs]) => bs && as.import(bs).push(new parser_1.Node("\u0018" /* Command.Cancel */)) && as))]), ([{
@@ -7388,6 +7381,7 @@ exports.textlink = (0, combinator_1.lazy)(() => (0, combinator_1.constraint)(8 /
7388
7381
  }, {
7389
7382
  value: params = undefined
7390
7383
  } = {}], context) => {
7384
+ if (context.state & 8 /* State.link */) return new parser_1.List([new parser_1.Node(context.source.slice(context.position - context.range, context.position))]);
7391
7385
  if (content.last.value === "\u001F" /* Command.Separator */) {
7392
7386
  content.pop();
7393
7387
  if (params === undefined) {
@@ -7407,7 +7401,7 @@ exports.textlink = (0, combinator_1.lazy)(() => (0, combinator_1.constraint)(8 /
7407
7401
  }
7408
7402
  if (content.length !== 0 && (0, visibility_1.trimBlankNodeEnd)(content).length === 0) return;
7409
7403
  return new parser_1.List([new parser_1.Node(parse(content, params, context))]);
7410
- })))));
7404
+ }));
7411
7405
  exports.medialink = (0, combinator_1.lazy)(() => (0, combinator_1.constraint)(8 /* State.link */ | 4 /* State.media */, (0, combinator_1.state)(251 /* State.linkers */, (0, combinator_1.bind)((0, combinator_1.sequence)([(0, combinator_1.dup)((0, combinator_1.surround)('[', (0, combinator_1.union)([inline_1.media, inline_1.shortmedia]), ']')), (0, combinator_1.dup)((0, combinator_1.surround)(/{(?![{}])/y, (0, combinator_1.precedence)(9, (0, combinator_1.inits)([exports.uri, (0, combinator_1.some)(exports.option)])), / ?}/y))]), ([{
7412
7406
  value: content
7413
7407
  }, {
@@ -7857,11 +7851,11 @@ exports.ruby = (0, combinator_1.lazy)(() => (0, combinator_1.bind)((0, combinato
7857
7851
  value: ruby = ''
7858
7852
  } = {}]) => acc.import(ruby ? new parser_1.List([new parser_1.Node(text), new parser_1.Node((0, dom_1.html)('rp', '(')), new parser_1.Node((0, dom_1.html)('rt', ruby)), new parser_1.Node((0, dom_1.html)('rp', ')'))]) : new parser_1.List([new parser_1.Node(text), new parser_1.Node((0, dom_1.html)('rt'))])), new parser_1.List())))))]);
7859
7853
  default:
7860
- return new parser_1.List([new parser_1.Node((0, dom_1.html)('ruby', (0, dom_1.defrag)((0, util_1.unwrap)(new parser_1.List([new parser_1.Node(texts.foldr(({
7854
+ return new parser_1.List([new parser_1.Node((0, dom_1.html)('ruby', (0, dom_1.defrag)((0, util_1.unwrap)(new parser_1.List([new parser_1.Node(texts.foldl((acc, {
7861
7855
  value
7862
- }, acc) => value + ' ' + acc, '').slice(0, -1)), new parser_1.Node((0, dom_1.html)('rp', '(')), new parser_1.Node((0, dom_1.html)('rt', rubies.foldr(({
7856
+ }) => acc ? acc + ' ' + value : value, '')), new parser_1.Node((0, dom_1.html)('rp', '(')), new parser_1.Node((0, dom_1.html)('rt', rubies.foldl((acc, {
7863
7857
  value
7864
- }, acc) => value + ' ' + acc, '').trim())), new parser_1.Node((0, dom_1.html)('rp', ')'))])))))]);
7858
+ }) => acc ? acc + ' ' + value : value, '').trim())), new parser_1.Node((0, dom_1.html)('rp', ')'))])))))]);
7865
7859
  }
7866
7860
  }));
7867
7861
  const delimiter = /[$"`\[\](){}<>()[]{}|]|\\?\n/y;
@@ -8309,7 +8303,7 @@ const extension_1 = __webpack_require__(6193);
8309
8303
  const source_1 = __webpack_require__(8745);
8310
8304
  exports.MAX_SEGMENT_SIZE = 100_000; // 100,000 bytes (Max value size of FDB)
8311
8305
  exports.MAX_INPUT_SIZE = exports.MAX_SEGMENT_SIZE * 10;
8312
- const parser = (0, combinator_1.union)([(0, combinator_1.some)(source_1.emptyline), input => {
8306
+ const parser = (0, combinator_1.union)([(0, combinator_1.some)(source_1.emptyline, exports.MAX_SEGMENT_SIZE + 1), input => {
8313
8307
  const {
8314
8308
  context: {
8315
8309
  source,
@@ -8335,7 +8329,7 @@ const parser = (0, combinator_1.union)([(0, combinator_1.some)(source_1.emptylin
8335
8329
  case '$':
8336
8330
  return (0, extension_1.segment)(input);
8337
8331
  }
8338
- }, (0, combinator_1.some)(source_1.contentline)]);
8332
+ }, (0, combinator_1.some)(source_1.contentline, exports.MAX_SEGMENT_SIZE + 1)]);
8339
8333
  function* segment(source) {
8340
8334
  if (!validate(source, exports.MAX_INPUT_SIZE)) return yield `${"\u0007" /* Command.Error */}Too large input over ${exports.MAX_INPUT_SIZE.toLocaleString('en')} bytes.\n${source.slice(0, 1001)}`;
8341
8335
  for (let position = 0; position < source.length;) {
package/markdown.d.ts CHANGED
@@ -714,7 +714,7 @@ export namespace MarkdownParser {
714
714
  // [#index]
715
715
  // [#index|signature]
716
716
  Inline<'extension/index'>,
717
- Parser<string | HTMLElement, Context, [
717
+ Parser<HTMLAnchorElement, Context, [
718
718
  InlineParser,
719
719
  IndexParser.SignatureParser,
720
720
  ]> {
@@ -767,7 +767,7 @@ export namespace MarkdownParser {
767
767
  // { uri }
768
768
  // [abc]{uri nofollow}
769
769
  Inline<'link'>,
770
- Parser<HTMLAnchorElement | HTMLSpanElement, Context, [
770
+ Parser<HTMLAnchorElement | HTMLSpanElement | string, Context, [
771
771
  LinkParser.MediaLinkParser,
772
772
  LinkParser.TextLinkParser,
773
773
  ]> {
@@ -775,7 +775,7 @@ export namespace MarkdownParser {
775
775
  export namespace LinkParser {
776
776
  export interface TextLinkParser extends
777
777
  Inline<'link/textlink'>,
778
- Parser<HTMLAnchorElement | HTMLSpanElement, Context, [
778
+ Parser<HTMLAnchorElement | HTMLSpanElement | string, Context, [
779
779
  Parser<List<Node<string | HTMLElement>>, Context, [
780
780
  InlineParser,
781
781
  ]>,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "securemark",
3
- "version": "0.295.4",
3
+ "version": "0.295.5",
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",
@@ -30,7 +30,7 @@ describe('Unit: parser/api/bind', () => {
30
30
  const cfgs = { notes: { references: html('ol') } };
31
31
 
32
32
  it('huge input', () => {
33
- const iter = bind(html('div'), { ...cfgs, id: '' }).parse(`${'\n'.repeat(10 * 1000 ** 2)}`);
33
+ const iter = bind(html('div'), { ...cfgs, id: '' }).parse(`${'\n'.repeat(1e6 + 1)}`);
34
34
  assert.deepStrictEqual(
35
35
  inspect(iter),
36
36
  [
@@ -42,7 +42,7 @@ describe('Unit: parser/api/bind', () => {
42
42
  it('huge segment', function () {
43
43
  this.timeout(10 * 1000);
44
44
 
45
- const iter = bind(html('div'), { ...cfgs, id: '' }).parse(`${'\n'.repeat(1000 ** 2 - 1)}`);
45
+ const iter = bind(html('div'), { ...cfgs, id: '' }).parse(`${'\n'.repeat(1e5 + 1)}`);
46
46
  assert.deepStrictEqual(
47
47
  inspect(iter, 3),
48
48
  [
@@ -6,7 +6,7 @@ describe('Unit: parser/api/parse', () => {
6
6
  describe('parse', () => {
7
7
  it('huge input', () => {
8
8
  assert.deepStrictEqual(
9
- [...parse(`${'\n'.repeat(10 * 1000 ** 2)}`, { id: '' }).children].map(el => el.outerHTML),
9
+ [...parse(`${'\n'.repeat(1e6 + 1)}`, { id: '' }).children].map(el => el.outerHTML),
10
10
  [
11
11
  '<h1 class="error">Error: Too large input over 1,000,000 bytes.</h1>',
12
12
  `<pre class="error" translate="no">${'\n'.repeat(997)}...</pre>`,
@@ -15,7 +15,7 @@ describe('Unit: parser/api/parse', () => {
15
15
 
16
16
  it('huge segment', () => {
17
17
  assert.deepStrictEqual(
18
- [...parse(`${'\n'.repeat(100 * 1000 + 1)}`, { id: '' }).children].map(el => el.outerHTML),
18
+ [...parse(`${'\n'.repeat(1e5 + 1)}`, { id: '' }).children].map(el => el.outerHTML),
19
19
  [
20
20
  '<h1 class="error">Error: Too large segment over 100,000 bytes.</h1>',
21
21
  `<pre class="error" translate="no">${'\n'.repeat(997)}...</pre>`,
@@ -360,22 +360,32 @@ describe('Unit: parser/api/parse', () => {
360
360
  ]);
361
361
  });
362
362
 
363
- it('backtrack', function () {
364
- this.timeout(5000);
363
+ it('backtrack 1', () => {
365
364
  // 最悪計算量での実行速度はCommonMarkの公式JS実装の32nに対して50-400%程度。
366
365
  // 6n = annotation + reference + link + url/math + ruby + text
367
- const source = `((([[[[#$[${'.'.repeat(16664)}]]]`;
368
366
  assert.deepStrictEqual(
369
- [...parse(source, {}, new Context({ resources: { clock: 100000, recursions: [100] } })).children]
367
+ [...parse(`((([[[[#$[${'.'.repeat(16665)}`, {}, new Context({ resources: { clock: 100000, recursions: [100] } })).children]
368
+ .map(el => el.tagName),
369
+ ['P']);
370
+ });
371
+
372
+ it('backtrack 1 error', () => {
373
+ assert.deepStrictEqual(
374
+ [...parse(`((([[[[#$[${'.'.repeat(16665 + 1)}`, {}, new Context({ resources: { clock: 100000, recursions: [100] } })).children]
375
+ .map(el => el.tagName),
376
+ ['H1', 'PRE']);
377
+ });
378
+
379
+ it('backtrack 2', () => {
380
+ assert.deepStrictEqual(
381
+ [...parse(`((([[[[#$[${'.'.repeat(16664)}]]]`, {}, new Context({ resources: { clock: 100000, recursions: [100] } })).children]
370
382
  .map(el => el.tagName),
371
383
  ['P', 'OL']);
372
384
  });
373
385
 
374
- it('backtrack error', function () {
375
- this.timeout(5000);
376
- const source = `((([[[[#$[${'.'.repeat(16664 + 1)}]]]`;
386
+ it('backtrack 2 error', () => {
377
387
  assert.deepStrictEqual(
378
- [...parse(source, {}, new Context({ resources: { clock: 100000, recursions: [100] } })).children]
388
+ [...parse(`((([[[[#$[${'.'.repeat(16664 + 1)}]]]`, {}, new Context({ resources: { clock: 100000, recursions: [100] } })).children]
379
389
  .map(el => el.tagName),
380
390
  ['H1', 'PRE']);
381
391
  });
@@ -100,13 +100,11 @@ const s1 = lazy(() => surround(
100
100
  setBacktrack(context, 2 | Backtrack.link, head);
101
101
  }
102
102
  else {
103
- context.state ^= State.link;
104
103
  if (!isBacktrack(context, 1 | Backtrack.link) && !textlink({ context })) {
105
104
  setBacktrack(context, 2 | Backtrack.link, head);
106
105
  }
107
106
  context.position = position;
108
107
  context.range = range;
109
- context.state ^= State.link;
110
108
  }
111
109
  }
112
110
  return as.import(bs as List<Node<string>>).import(cs);
@@ -29,29 +29,23 @@ export const index: IndexParser = lazy(() => constraint(State.index, fmap(indexe
29
29
  : undefined,
30
30
  undefined)),
31
31
  ns => {
32
- if (ns.length === 1) {
33
- const el = ns.head!.value as HTMLElement;
34
- return new List([
35
- new Node(define(el, {
36
- id: el.id ? null : undefined,
37
- class: 'index',
38
- href: el.id ? `#${el.id}` : undefined,
39
- }))
40
- ]);
41
- }
42
- else {
43
- assert(ns.last?.value === '');
44
- ns.pop();
45
- return ns;
46
- }
32
+ assert(ns.length === 1);
33
+ const el = ns.head!.value as HTMLAnchorElement;
34
+ return new List([
35
+ new Node(define(el, {
36
+ id: el.id ? null : undefined,
37
+ class: 'index',
38
+ href: el.id ? `#${el.id}` : undefined,
39
+ }))
40
+ ]);
47
41
  })));
48
42
 
49
43
  export const signature: IndexParser.SignatureParser = lazy(() => validate('|', surround(
50
44
  str(/\|(?!\\?\s)/y),
51
- some(union([
45
+ precedence(9, some(union([
52
46
  unsafehtmlentity,
53
47
  some(txt, /(?:[$"`\[\](){}<>()[]{}|])/y),
54
- ]), ']'),
48
+ ]), ']')),
55
49
  /(?=])/y,
56
50
  false,
57
51
  [3 | Backtrack.escapable],
@@ -15,12 +15,12 @@ const optspec = {
15
15
  } as const;
16
16
  Object.setPrototypeOf(optspec, null);
17
17
 
18
- export const textlink: LinkParser.TextLinkParser = lazy(() => constraint(State.link,
19
- precedence(1, state(State.linkers,
20
- bind(subsequence([
21
- dup(surround(
18
+ export const textlink: LinkParser.TextLinkParser = lazy(() => bind(
19
+ subsequence([
20
+ constraint(State.link, state(State.linkers, dup(surround(
22
21
  '[',
23
- trimBlankStart(some(union([inline]), ']', [[']', 1]])),
22
+ precedence(1,
23
+ trimBlankStart(some(union([inline]), ']', [[']', 1]]))),
24
24
  ']',
25
25
  true,
26
26
  [3 | Backtrack.common | Backtrack.link, 2 | Backtrack.ruby],
@@ -30,7 +30,7 @@ export const textlink: LinkParser.TextLinkParser = lazy(() => constraint(State.l
30
30
  return void setBacktrack(context, 2 | Backtrack.link | Backtrack.ruby, head);
31
31
  }
32
32
  return ns.push(new Node(Command.Separator)) && ns;
33
- })),
33
+ })))),
34
34
  // `{ `と`{`で個別にバックトラックが発生し+1nされる。
35
35
  // 自己再帰的にパースしてもオプションの不要なパースによる計算量の増加により相殺される。
36
36
  dup(surround(
@@ -43,6 +43,7 @@ export const textlink: LinkParser.TextLinkParser = lazy(() => constraint(State.l
43
43
  bs && as.import(bs).push(new Node(Command.Cancel)) && as)),
44
44
  ]),
45
45
  ([{ value: content }, { value: params = undefined } = {}], context) => {
46
+ if (context.state & State.link) return new List([new Node(context.source.slice(context.position - context.range, context.position))]);
46
47
  if (content.last!.value === Command.Separator) {
47
48
  content.pop();
48
49
  if (params === undefined) {
@@ -69,7 +70,7 @@ export const textlink: LinkParser.TextLinkParser = lazy(() => constraint(State.l
69
70
  assert(content.head?.value !== '');
70
71
  if (content.length !== 0 && trimBlankNodeEnd(content).length === 0) return;
71
72
  return new List([new Node(parse(content, params as List<Node<string>>, context))]);
72
- })))));
73
+ }));
73
74
 
74
75
  export const medialink: LinkParser.MediaLinkParser = lazy(() => constraint(State.link | State.media,
75
76
  state(State.linkers,
@@ -53,9 +53,9 @@ export const ruby: RubyParser = lazy(() => bind(
53
53
  assert(rubies.length > 0);
54
54
  return new List([
55
55
  new Node(html('ruby', defrag(unwrap(new List<Node<string | HTMLElement>>([
56
- new Node(texts.foldr(({ value }, acc) => value + ' ' + acc, '').slice(0, -1)),
56
+ new Node(texts.foldl((acc, { value }) => acc ? acc + ' ' + value : value, '')),
57
57
  new Node(html('rp', '(')),
58
- new Node(html('rt', rubies.foldr(({ value }, acc) => value + ' ' + acc, '').trim())),
58
+ new Node(html('rt', rubies.foldl((acc, { value }) => acc ? acc + ' ' + value : value, '').trim())),
59
59
  new Node(html('rp', ')')),
60
60
  ]))))),
61
61
  ]);
@@ -170,6 +170,8 @@ describe('Unit: parser/inline', () => {
170
170
  assert.deepStrictEqual(inspect(parser, input('[#@a/http://host/(<bdi>)]</bdi>', new Context())), [['<a class="index" href="#index::@a/http://host/(&lt;bdi&gt;)">@a/http://host/<span class="paren">(<span class="invalid">&lt;bdi&gt;</span>)</span></a>', '</bdi', '>'], '']);
171
171
  assert.deepStrictEqual(inspect(parser, input('[#a|<bdi>]</bdi>', new Context())), [['<a class="index" href="#index::a|&lt;bdi&gt;">a|<span class="invalid">&lt;bdi&gt;</span></a>', '</bdi', '>'], '']);
172
172
  assert.deepStrictEqual(inspect(parser, input('[[#a|<bdi>]</bdi>', new Context())), [['[', '<a class="index" href="#index::a|&lt;bdi&gt;">a|<span class="invalid">&lt;bdi&gt;</span></a>', '</bdi', '>'], '']);
173
+ assert.deepStrictEqual(inspect(parser, input('[]{"}[[""]]}]', new Context())), [['<a class="url" href="&quot;">"</a>', '<sup class="reference"><span>""</span></sup>', '}', ']'], '']);
174
+ assert.deepStrictEqual(inspect(parser, input('[ []{"}[[""]]}]', new Context())), [['[', ' ', '<a class="url" href="&quot;">"</a>', '<sup class="reference"><span>""</span></sup>', '}', ']'], '']);
173
175
  });
174
176
 
175
177
  it('uri', () => {
@@ -4,12 +4,12 @@ import { Command } from './context';
4
4
  describe('Unit: parser/segment', () => {
5
5
  describe('segment', () => {
6
6
  it('huge input', () => {
7
- const result = segment(`${'\n'.repeat(10 * 1000 ** 2)}`).next().value?.split('\n', 1)[0];
7
+ const result = segment(`${'\n'.repeat(1e6 + 1)}`).next().value?.split('\n', 1)[0];
8
8
  assert(result?.startsWith(`${Command.Error}Too large input`));
9
9
  });
10
10
 
11
11
  it('huge segment', () => {
12
- const result = segment(`${'\n'.repeat(1000 ** 2 - 1)}`).next().value?.split('\n', 1)[0];
12
+ const result = segment(`${'\n'.repeat(1e5 + 1)}`).next().value?.split('\n', 1)[0];
13
13
  assert(result?.startsWith(`${Command.Error}Too large segment`));
14
14
  });
15
15
 
@@ -13,7 +13,7 @@ export const MAX_SEGMENT_SIZE = 100_000; // 100,000 bytes (Max value size of FDB
13
13
  export const MAX_INPUT_SIZE = MAX_SEGMENT_SIZE * 10;
14
14
 
15
15
  const parser: SegmentParser = union([
16
- some(emptyline),
16
+ some(emptyline, MAX_SEGMENT_SIZE + 1),
17
17
  input => {
18
18
  const { context: { source, position } } = input;
19
19
  if (position === source.length) return;
@@ -36,7 +36,7 @@ const parser: SegmentParser = union([
36
36
  return extension(input);
37
37
  }
38
38
  },
39
- some(contentline),
39
+ some(contentline, MAX_SEGMENT_SIZE + 1),
40
40
  ]) as any;
41
41
 
42
42
  export function* segment(source: string): Generator<string, undefined, undefined> {