n3 2.11.1 → 2.11.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.
- package/README.md +7 -0
- package/browser/n3.esm.min.js +13 -13
- package/browser/n3.min.js +13 -13
- package/lib/N3Lexer.js +148 -133
- package/lib/N3Parser.js +24 -18
- package/lib/N3Writer.js +8 -5
- package/lib/Util.js +1 -1
- package/package.json +2 -29
- package/src/N3Lexer.js +162 -142
- package/src/N3Parser.js +26 -18
- package/src/N3Writer.js +8 -5
- package/src/Util.js +1 -1
package/src/N3Parser.js
CHANGED
|
@@ -54,6 +54,10 @@ export default class N3Parser {
|
|
|
54
54
|
// Disable parsing of unsupported versions by default
|
|
55
55
|
this._parseUnsupportedVersions = !!options.parseUnsupportedVersions;
|
|
56
56
|
this._version = options.version;
|
|
57
|
+
// Maximum nesting depth of triple terms (default 1024; Infinity disables the limit)
|
|
58
|
+
const maxTripleTermDepth = options.maxTripleTermDepth;
|
|
59
|
+
this._maxTripleTermDepth = maxTripleTermDepth === Infinity ||
|
|
60
|
+
Number.isInteger(maxTripleTermDepth) && maxTripleTermDepth >= 0 ? maxTripleTermDepth : 1024;
|
|
57
61
|
}
|
|
58
62
|
|
|
59
63
|
// ## Static class methods
|
|
@@ -88,6 +92,19 @@ export default class N3Parser {
|
|
|
88
92
|
}
|
|
89
93
|
}
|
|
90
94
|
|
|
95
|
+
// ### `_enterTripleTerm` stores the current parsing context when entering a triple term,
|
|
96
|
+
// failing if triple terms nest deeper than the maximum depth
|
|
97
|
+
_enterTripleTerm(type, subject, predicate, token) {
|
|
98
|
+
if (this._tripleTermDepth >= this._maxTripleTermDepth) {
|
|
99
|
+
this._error(`Triple terms nested deeper than ${this._maxTripleTermDepth} level${this._maxTripleTermDepth === 1 ? '' : 's'}`, token);
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
102
|
+
this._tripleTermDepth++;
|
|
103
|
+
this._saveContext(type, this._graph, subject, predicate, null);
|
|
104
|
+
this._graph = null;
|
|
105
|
+
return true;
|
|
106
|
+
}
|
|
107
|
+
|
|
91
108
|
// ### `_saveContext` stores the current parsing context
|
|
92
109
|
// when entering a new scope (list, blank node, formula)
|
|
93
110
|
_saveContext(type, graph, subject, predicate, object) {
|
|
@@ -338,13 +355,9 @@ export default class N3Parser {
|
|
|
338
355
|
case '<<(':
|
|
339
356
|
if (!this._n3Mode)
|
|
340
357
|
return this._error('Disallowed triple term as subject', token);
|
|
341
|
-
this.
|
|
342
|
-
this._graph = null;
|
|
343
|
-
return this._readSubject;
|
|
358
|
+
return this._enterTripleTerm('<<(', null, null, token) && this._readSubject;
|
|
344
359
|
case '<<':
|
|
345
|
-
this.
|
|
346
|
-
this._graph = null;
|
|
347
|
-
return this._readSubject;
|
|
360
|
+
return this._enterTripleTerm('<<', null, null, token) && this._readSubject;
|
|
348
361
|
default:
|
|
349
362
|
// Read the subject entity
|
|
350
363
|
if ((this._subject = this._readEntity(token)) === undefined)
|
|
@@ -489,13 +502,9 @@ export default class N3Parser {
|
|
|
489
502
|
this._graph = this._factory.blankNode());
|
|
490
503
|
return this._readInFormulaContext;
|
|
491
504
|
case '<<(':
|
|
492
|
-
this.
|
|
493
|
-
this._graph = null;
|
|
494
|
-
return this._readSubject;
|
|
505
|
+
return this._enterTripleTerm('<<(', this._subject, this._predicate, token) && this._readSubject;
|
|
495
506
|
case '<<':
|
|
496
|
-
this.
|
|
497
|
-
this._graph = null;
|
|
498
|
-
return this._readSubject;
|
|
507
|
+
return this._enterTripleTerm('<<', this._subject, this._predicate, token) && this._readSubject;
|
|
499
508
|
default:
|
|
500
509
|
// Read the object entity
|
|
501
510
|
if ((this._object = this._readEntity(token)) === undefined)
|
|
@@ -715,13 +724,9 @@ export default class N3Parser {
|
|
|
715
724
|
this._subject = null;
|
|
716
725
|
return this._readInFormulaContext;
|
|
717
726
|
case '<<(':
|
|
718
|
-
this._saveContext('<<(', this._graph, null, null, null);
|
|
719
|
-
this._graph = null;
|
|
720
|
-
next = this._readSubject;
|
|
721
|
-
break;
|
|
722
727
|
case '<<':
|
|
723
|
-
this.
|
|
724
|
-
|
|
728
|
+
if (!this._enterTripleTerm(token.type, null, null, token))
|
|
729
|
+
return;
|
|
725
730
|
next = this._readSubject;
|
|
726
731
|
break;
|
|
727
732
|
default:
|
|
@@ -1271,6 +1276,7 @@ export default class N3Parser {
|
|
|
1271
1276
|
const quad = this._createQuad(this._subject, this._predicate, this._object,
|
|
1272
1277
|
this._graph, this._inversePredicate);
|
|
1273
1278
|
this._restoreContext('<<(', token);
|
|
1279
|
+
this._tripleTermDepth--;
|
|
1274
1280
|
|
|
1275
1281
|
// If we're in a list, continue processing that list
|
|
1276
1282
|
const stack = this._contextStack, parent = stack.length && stack[stack.length - 1];
|
|
@@ -1306,6 +1312,7 @@ export default class N3Parser {
|
|
|
1306
1312
|
this._tripleTerm = null;
|
|
1307
1313
|
const reifier = this._readTripleTerm();
|
|
1308
1314
|
this._restoreContext('<<', token);
|
|
1315
|
+
this._tripleTermDepth--;
|
|
1309
1316
|
|
|
1310
1317
|
// // If we're in a list, continue processing that list
|
|
1311
1318
|
const stack = this._contextStack, parent = stack.length && stack[stack.length - 1];
|
|
@@ -1651,6 +1658,7 @@ export default class N3Parser {
|
|
|
1651
1658
|
this._prefixChanges = null;
|
|
1652
1659
|
this._quantifiedChanges = null;
|
|
1653
1660
|
this._emptyFormula = false;
|
|
1661
|
+
this._tripleTermDepth = 0;
|
|
1654
1662
|
|
|
1655
1663
|
let readToken = token => {
|
|
1656
1664
|
return this._readCallback = this._readCallback(token);
|
package/src/N3Writer.js
CHANGED
|
@@ -59,6 +59,8 @@ export default class N3Writer {
|
|
|
59
59
|
this._lineMode = false;
|
|
60
60
|
this._graph = DEFAULTGRAPH;
|
|
61
61
|
this._prefixIRIs = Object.create(null);
|
|
62
|
+
// Escaped prefix IRIs and names for the prefix matcher, computed once per prefix
|
|
63
|
+
this._prefixPatterns = Object.create(null);
|
|
62
64
|
if (options.baseIRI) {
|
|
63
65
|
this._baseIri = new BaseIRI(options.baseIRI);
|
|
64
66
|
if (options.writeBase)
|
|
@@ -316,18 +318,19 @@ export default class N3Writer {
|
|
|
316
318
|
}
|
|
317
319
|
// Store and write the prefix
|
|
318
320
|
this._prefixIRIs[iri] = (prefix += ':');
|
|
321
|
+
this._prefixPatterns[iri] = [escapeRegex(iri), escapeRegex(prefix)];
|
|
319
322
|
this._write(`@prefix ${prefix} <${iri}>.\n`);
|
|
320
323
|
}
|
|
321
324
|
// Recreate the prefix matcher
|
|
322
325
|
if (hasPrefixes) {
|
|
323
326
|
this._hasPrefixes = true;
|
|
324
327
|
let IRIlist = '', prefixList = '';
|
|
325
|
-
for (const prefixIRI in this.
|
|
326
|
-
|
|
327
|
-
|
|
328
|
+
for (const prefixIRI in this._prefixPatterns) {
|
|
329
|
+
const [IRIpattern, prefixPattern] = this._prefixPatterns[prefixIRI];
|
|
330
|
+
IRIlist += IRIlist ? `|${IRIpattern}` : IRIpattern;
|
|
331
|
+
prefixList += prefixList ? `|${prefixPattern}` : prefixPattern;
|
|
328
332
|
}
|
|
329
|
-
|
|
330
|
-
this._prefixRegex = new RegExp(`^(?:${prefixList})[^\/]*$|` +
|
|
333
|
+
this._prefixRegex = new RegExp(`^(?:${prefixList})[^/]*$|` +
|
|
331
334
|
`^(${IRIlist})([_a-zA-Z0-9](?:\\.?[\\-_a-zA-Z0-9])*)$`);
|
|
332
335
|
}
|
|
333
336
|
// End a prefix block with a newline
|
package/src/Util.js
CHANGED