rdfxml-streaming-parser
Advanced tools
Comparing version 1.0.0 to 1.0.1
# Changelog | ||
All notable changes to this project will be documented in this file. | ||
<a name="v1.0.1"></a> | ||
## [v1.0.1](https://github.com/rdfjs/rdfxml-streaming-parser.js/compare/v1.0.0...v1.0.1) - 2018-10-09 | ||
### Fixed | ||
* [Throw an error on li attributes on node elements](https://github.com/rdfjs/rdfxml-streaming-parser.js/commit/affb69bafb7f6ccfa72be731a7058314a541e2b4) | ||
* [Throw errors on rdf:aboutEach and rdf:aboutEachPrefix](https://github.com/rdfjs/rdfxml-streaming-parser.js/commit/d981af760f5b4a21d73d325f4105da203bd8223c) | ||
* [Add stricter NCName validation](https://github.com/rdfjs/rdfxml-streaming-parser.js/commit/25d97be70d88e18aed856c9aae15741cc9300c5e) | ||
* [Make parseType and resource interactions more strict](https://github.com/rdfjs/rdfxml-streaming-parser.js/commit/25e397285db03e8094197515394ee62f88f29761) | ||
* [Add blacklists for forbidden node and property element names](https://github.com/rdfjs/rdfxml-streaming-parser.js/commit/1e812fcbaef4bb4ad112f3eec83e3ce91bc97d51) | ||
<a name="1.0.0"></a> | ||
## [1.0.0] - 2018-09-04 | ||
* Initial release |
@@ -13,2 +13,5 @@ /// <reference types="node" /> | ||
}; | ||
static readonly FORBIDDEN_NODE_ELEMENTS: string[]; | ||
static readonly FORBIDDEN_PROPERTY_ELEMENTS: string[]; | ||
static readonly NCNAME_MATCHER: RegExp; | ||
private readonly dataFactory; | ||
@@ -54,2 +57,8 @@ private readonly baseIRI; | ||
valueToUri(value: string, activeTag: IActiveTag): RDF.NamedNode; | ||
/** | ||
* Validate the given value as an NCName: https://www.w3.org/TR/xml-names/#NT-NCName | ||
* If it is invalid, an error will be emitted. | ||
* @param {string} value A value. | ||
*/ | ||
validateNcname(value: string): void; | ||
protected attachSaxListeners(): void; | ||
@@ -66,4 +75,5 @@ /** | ||
* @param {IActiveTag} parentTag The parent tag or null. | ||
* @param {boolean} rootTag If we are currently processing the root tag. | ||
*/ | ||
protected onTagResource(tag: Tag, activeTag: IActiveTag, parentTag: IActiveTag): void; | ||
protected onTagResource(tag: Tag, activeTag: IActiveTag, parentTag: IActiveTag, rootTag: boolean): void; | ||
/** | ||
@@ -70,0 +80,0 @@ * Handle the given property element in property-mode. |
@@ -195,2 +195,13 @@ "use strict"; | ||
} | ||
/** | ||
* Validate the given value as an NCName: https://www.w3.org/TR/xml-names/#NT-NCName | ||
* If it is invalid, an error will be emitted. | ||
* @param {string} value A value. | ||
*/ | ||
validateNcname(value) { | ||
// Validate term as an NCName: https://www.w3.org/TR/xml-names/#NT-NCName | ||
if (!RdfXmlParser.NCNAME_MATCHER.test(value)) { | ||
this.emit('error', new Error(`Not a valid NCName: ${value}`)); | ||
} | ||
} | ||
attachSaxListeners() { | ||
@@ -246,3 +257,3 @@ this.saxStream.on('error', (error) => this.emit('error', error)); | ||
if (currentParseType === ParseType.RESOURCE) { | ||
this.onTagResource(tag, activeTag, parentTag); | ||
this.onTagResource(tag, activeTag, parentTag, !parentTag); | ||
} | ||
@@ -258,4 +269,5 @@ else { // currentParseType === ParseType.PROPERTY | ||
* @param {IActiveTag} parentTag The parent tag or null. | ||
* @param {boolean} rootTag If we are currently processing the root tag. | ||
*/ | ||
onTagResource(tag, activeTag, parentTag) { | ||
onTagResource(tag, activeTag, parentTag, rootTag) { | ||
const tagExpanded = RdfXmlParser.expandPrefixedTerm(tag.name, activeTag.ns); | ||
@@ -266,2 +278,6 @@ activeTag.childrenParseType = ParseType.PROPERTY; | ||
if (tagExpanded.uri === RdfXmlParser.RDF) { | ||
// Check forbidden property element names | ||
if (!rootTag && RdfXmlParser.FORBIDDEN_NODE_ELEMENTS.indexOf(tagExpanded.local) >= 0) { | ||
this.emit('error', new Error(`Illegal node element name: ${tagExpanded.local}`)); | ||
} | ||
switch (tagExpanded.local) { | ||
@@ -300,2 +316,3 @@ case 'RDF': | ||
} | ||
this.validateNcname(attributeValue); | ||
activeSubjectValue = '#' + attributeValue; | ||
@@ -309,5 +326,9 @@ claimSubjectNodeId = true; | ||
} | ||
this.validateNcname(attributeValue); | ||
activeSubjectValue = attributeValue; | ||
subjectValueBlank = true; | ||
continue; | ||
case 'bagID': | ||
this.emit('error', new Error(`rdf:bagID is not supported.`)); | ||
continue; | ||
case 'type': | ||
@@ -317,2 +338,11 @@ // Emit the rdf:type later as named node instead of the default literal | ||
continue; | ||
case 'aboutEach': | ||
this.emit('error', new Error(`rdf:aboutEach is not supported.`)); | ||
continue; | ||
case 'aboutEachPrefix': | ||
this.emit('error', new Error(`rdf:aboutEachPrefix is not supported.`)); | ||
continue; | ||
case 'li': | ||
this.emit('error', new Error(`rdf:li on node elements are not supported.`)); | ||
continue; | ||
} | ||
@@ -412,5 +442,10 @@ } | ||
} | ||
// Check forbidden property element names | ||
if (tagExpanded.uri === RdfXmlParser.RDF | ||
&& RdfXmlParser.FORBIDDEN_PROPERTY_ELEMENTS.indexOf(tagExpanded.local) >= 0) { | ||
this.emit('error', new Error(`Illegal property element name: ${tagExpanded.local}`)); | ||
} | ||
activeTag.predicateSubPredicates = []; | ||
activeTag.predicateSubObjects = []; | ||
let parseTypeResource = false; | ||
let parseType = false; | ||
let attributedProperty = false; | ||
@@ -433,4 +468,4 @@ // Collect all attributes as triples | ||
} | ||
if (parseTypeResource) { | ||
this.emit('error', new Error(`rdf:parseType="Resource" is not allowed on property elements with rdf:resource (${propertyAttributeValue})`)); | ||
if (parseType) { | ||
this.emit('error', new Error(`rdf:parseType is not allowed on property elements with rdf:resource (${propertyAttributeValue})`)); | ||
} | ||
@@ -445,4 +480,4 @@ activeTag.hadChildren = true; | ||
} | ||
if (parseTypeResource) { | ||
this.emit('error', new Error(`rdf:parseType="Resource" is not allowed on property elements with rdf:datatype (${propertyAttributeValue})`)); | ||
if (parseType) { | ||
this.emit('error', new Error(`rdf:parseType is not allowed on property elements with rdf:datatype (${propertyAttributeValue})`)); | ||
} | ||
@@ -458,5 +493,6 @@ activeTag.datatype = this.valueToUri(propertyAttributeValue, activeTag); | ||
} | ||
if (parseTypeResource) { | ||
this.emit('error', new Error(`rdf:parseType="Resource" is not allowed on property elements with rdf:nodeID (${propertyAttributeValue})`)); | ||
if (parseType) { | ||
this.emit('error', new Error(`rdf:parseType is not allowed on property elements with rdf:nodeID (${propertyAttributeValue})`)); | ||
} | ||
this.validateNcname(propertyAttributeValue); | ||
activeTag.hadChildren = true; | ||
@@ -466,16 +502,19 @@ activeSubSubjectValue = propertyAttributeValue; | ||
continue; | ||
case 'bagID': | ||
this.emit('error', new Error(`rdf:bagID is not supported.`)); | ||
continue; | ||
case 'parseType': | ||
// Validation | ||
if (attributedProperty) { | ||
this.emit('error', new Error(`rdf:parseType is not allowed when non-rdf:* property attributes are present`)); | ||
} | ||
if (activeTag.datatype) { | ||
this.emit('error', new Error(`rdf:parseType is not allowed on property elements with rdf:datatype (${activeTag.datatype.value})`)); | ||
} | ||
if (activeSubSubjectValue) { | ||
this.emit('error', new Error(`rdf:parseType is not allowed on property elements with rdf:nodeID or rdf:resource (${activeSubSubjectValue})`)); | ||
} | ||
if (propertyAttributeValue === 'Resource') { | ||
parseTypeResource = true; | ||
parseType = true; | ||
activeTag.childrenParseType = ParseType.PROPERTY; | ||
// Validation | ||
if (attributedProperty) { | ||
this.emit('error', new Error(`rdf:parseType="Resource" is not allowed when non-rdf:* property attributes are present`)); | ||
} | ||
if (activeTag.datatype) { | ||
this.emit('error', new Error(`rdf:parseType="Resource" is not allowed on property elements with rdf:datatype (${activeTag.datatype.value})`)); | ||
} | ||
if (activeSubSubjectValue) { | ||
this.emit('error', new Error(`rdf:parseType="Resource" is not allowed on property elements with rdf:nodeID or rdf:resource (${activeSubSubjectValue})`)); | ||
} | ||
// Turn this property element into a node element | ||
@@ -488,2 +527,3 @@ const nestedBNode = this.dataFactory.blankNode(); | ||
else if (propertyAttributeValue === 'Collection') { | ||
parseType = true; | ||
// Interpret children as being part of an rdf:List | ||
@@ -496,2 +536,3 @@ activeTag.hadChildren = true; | ||
else if (propertyAttributeValue === 'Literal') { | ||
parseType = true; | ||
// Interpret children as being part of a literal string | ||
@@ -503,2 +544,3 @@ activeTag.childrenTagsToString = true; | ||
case 'ID': | ||
this.validateNcname(propertyAttributeValue); | ||
activeTag.reifiedStatementId = this.valueToUri('#' + propertyAttributeValue, activeTag); | ||
@@ -518,3 +560,3 @@ this.claimNodeId(activeTag.reifiedStatementId); | ||
if (propertyAttributeKeyExpanded.prefix !== 'xml' && propertyAttributeKeyExpanded.uri) { | ||
if (parseTypeResource || activeTag.datatype) { | ||
if (parseType || activeTag.datatype) { | ||
this.emit('error', new Error(`Found illegal rdf:* properties on property element with attribute: ${propertyAttributeValue}`)); | ||
@@ -648,2 +690,28 @@ } | ||
}; | ||
RdfXmlParser.FORBIDDEN_NODE_ELEMENTS = [ | ||
'RDF', | ||
'ID', | ||
'about', | ||
'bagID', | ||
'parseType', | ||
'resource', | ||
'nodeID', | ||
'li', | ||
'aboutEach', | ||
'aboutEachPrefix', | ||
]; | ||
RdfXmlParser.FORBIDDEN_PROPERTY_ELEMENTS = [ | ||
'Description', | ||
'RDF', | ||
'ID', | ||
'about', | ||
'bagID', | ||
'parseType', | ||
'resource', | ||
'nodeID', | ||
'aboutEach', | ||
'aboutEachPrefix', | ||
]; | ||
// tslint:disable-next-line:max-line-length | ||
RdfXmlParser.NCNAME_MATCHER = /^([A-Za-z\xC0-\xD6\xD8-\xF6\u{F8}-\u{2FF}\u{370}-\u{37D}\u{37F}-\u{1FFF}\u{200C}-\u{200D}\u{2070}-\u{218F}\u{2C00}-\u{2FEF}\u{3001}-\u{D7FF}\u{F900}-\u{FDCF}\u{FDF0}-\u{FFFD}\u{10000}-\u{EFFFF}_])([A-Za-z\xC0-\xD6\xD8-\xF6\u{F8}-\u{2FF}\u{370}-\u{37D}\u{37F}-\u{1FFF}\u{200C}-\u{200D}\u{2070}-\u{218F}\u{2C00}-\u{2FEF}\u{3001}-\u{D7FF}\u{F900}-\u{FDCF}\u{FDF0}-\u{FFFD}\u{10000}-\u{EFFFF}_\-.0-9#xB7\u{0300}-\u{036F}\u{203F}-\u{2040}])*$/u; | ||
exports.RdfXmlParser = RdfXmlParser; | ||
@@ -650,0 +718,0 @@ var ParseType; |
{ | ||
"name": "rdfxml-streaming-parser", | ||
"version": "1.0.0", | ||
"version": "1.0.1", | ||
"description": "Streaming RDF/XML parser", | ||
@@ -16,8 +16,8 @@ "keywords": [ | ||
"typings": "index", | ||
"repository": "git@github.com:rubensworks/rdfxml-streaming-parser.js.git", | ||
"repository": "git@github.com:rdfjs/rdfxml-streaming-parser.js.git", | ||
"author": "Ruben Taelman <rubensworks@gmail.com>", | ||
"bugs": { | ||
"url": "https://github.com/rubensworks/rdfxml-streaming-parser.js/issues" | ||
"url": "https://github.com/rdfjs/rdfxml-streaming-parser.js/issues" | ||
}, | ||
"homepage": "https://github.com/rubensworks/rdfxml-streaming-parser.js#readme", | ||
"homepage": "https://github.com/rdfjs/rdfxml-streaming-parser.js#readme", | ||
"license": "MIT", | ||
@@ -44,6 +44,8 @@ "files": [ | ||
"jest-rdf": "^1.2.0", | ||
"manual-git-changelog": "^1.0.0", | ||
"pre-commit": "^1.2.2", | ||
"rdf-quad": "^1.2.2", | ||
"rdf-test-suite": "^1.0.0", | ||
"streamify-string": "^1.0.1", | ||
"ts-jest": "^23.0.1", | ||
"ts-jest": "^23.10.0", | ||
"tslint": "^5.8.0", | ||
@@ -54,2 +56,7 @@ "tslint-eslint-rules": "^5.3.1", | ||
"jest": { | ||
"globals": { | ||
"ts-jest": { | ||
"tsConfig": "test/tsconfig.json" | ||
} | ||
}, | ||
"setupTestFrameworkScriptFile": "jest-rdf", | ||
@@ -77,3 +84,6 @@ "transform": { | ||
"validate": "npm ls", | ||
"prepare": "npm run build" | ||
"prepare": "npm run build", | ||
"spec": "rdf-test-suite spec/parser.js https://www.w3.org/2013/RDFXMLTests/manifest.ttl -c .rdf-test-suite-cache/ -o summary", | ||
"spec-earl": "rdf-test-suite spec/parser.js https://www.w3.org/2013/RDFXMLTests/manifest.ttl -c .rdf-test-suite-cache/ -o earl -p spec/earl-meta.json > earl.ttl", | ||
"version": "manual-git-changelog onversion" | ||
}, | ||
@@ -80,0 +90,0 @@ "dependencies": { |
# RDF/XML Streaming Parser | ||
[![Build Status](https://travis-ci.org/rubensworks/rdfxml-streaming-parser.js.svg?branch=master)](https://travis-ci.org/rubensworks/rdfxml-streaming-parser.js) | ||
[![Coverage Status](https://coveralls.io/repos/github/rubensworks/rdfxml-streaming-parser.js/badge.svg?branch=master)](https://coveralls.io/github/rubensworks/rdfxml-streaming-parser.js?branch=master) | ||
[![npm version](https://badge.fury.io/js/rdfxml-streaming-parser.svg)](https://www.npmjs.com/package/rdfxml-streaming-parser) [![Greenkeeper badge](https://badges.greenkeeper.io/rubensworks/rdfxml-streaming-parser.js.svg)](https://greenkeeper.io/) | ||
[![Build Status](https://travis-ci.org/rdfjs/rdfxml-streaming-parser.js.svg?branch=master)](https://travis-ci.org/rdfjs/rdfxml-streaming-parser.js) | ||
[![Coverage Status](https://coveralls.io/repos/github/rdfjs/rdfxml-streaming-parser.js/badge.svg?branch=master)](https://coveralls.io/github/rdfjs/rdfxml-streaming-parser.js?branch=master) | ||
[![npm version](https://badge.fury.io/js/rdfxml-streaming-parser.svg)](https://www.npmjs.com/package/rdfxml-streaming-parser) [![Greenkeeper badge](https://badges.greenkeeper.io/rdfjs/rdfxml-streaming-parser.js.svg)](https://greenkeeper.io/) | ||
@@ -7,0 +7,0 @@ A [fast](https://gist.github.com/rubensworks/a351f394ca6b70d6ad4ec1adc691a453), _streaming_ [RDF/XML](https://www.w3.org/TR/rdf-syntax-grammar/) parser |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
49701
866
17