@@ -34,6 +34,11 @@ const {
3434 isAbsolute : _isAbsoluteIri
3535} = require ( './url' ) ;
3636
37+ const _HEX = '[0-9A-Fa-f]' ;
38+ const _UCHAR = '\\u' + _HEX + '{4}|\\U' + _HEX + '{8}' ;
39+ const IRIREF_RE = new RegExp ( '^([^\\x00-\\x20<>"{}|^`\\\\]|' + _UCHAR + ')*$' ) ;
40+ const LANG_RE = / ^ [ a - z A - Z ] + ( - [ a - z A - Z 0 - 9 ] + ) * $ / ;
41+
3742const api = { } ;
3843module . exports = api ;
3944
@@ -58,6 +63,11 @@ api.toRDF = (input, options) => {
5863 if ( graphName === '@default' ) {
5964 graphTerm = { termType : 'DefaultGraph' , value : '' } ;
6065 } else if ( _isAbsoluteIri ( graphName ) ) {
66+ // invalid graph IRI
67+ if ( ! IRIREF_RE . test ( graphName ) ) {
68+ continue ;
69+ }
70+
6171 if ( graphName . startsWith ( '_:' ) ) {
6272 graphTerm = { termType : 'BlankNode' } ;
6373 } else {
@@ -110,6 +120,11 @@ function _graphToRDF(dataset, graph, graphTerm, issuer, options) {
110120 continue ;
111121 }
112122
123+ // invalid subject IRI
124+ if ( ! IRIREF_RE . test ( id ) ) {
125+ continue ;
126+ }
127+
113128 // RDF predicate
114129 const predicate = {
115130 termType : property . startsWith ( '_:' ) ? 'BlankNode' : 'NamedNode' ,
@@ -121,6 +136,11 @@ function _graphToRDF(dataset, graph, graphTerm, issuer, options) {
121136 continue ;
122137 }
123138
139+ // invalid predicate IRI
140+ if ( ! IRIREF_RE . test ( property ) ) {
141+ continue ;
142+ }
143+
124144 // skip blank node predicates unless producing generalized RDF
125145 if ( predicate . termType === 'BlankNode' &&
126146 ! options . produceGeneralizedRdf ) {
@@ -226,6 +246,11 @@ function _objectToRDF(item, issuer, dataset, graphTerm) {
226246 let value = item [ '@value' ] ;
227247 const datatype = item [ '@type' ] || null ;
228248
249+ // invalid datatype IRI
250+ if ( datatype && ! IRIREF_RE . test ( datatype ) ) {
251+ return null ;
252+ }
253+
229254 // convert to XSD/JSON datatypes as appropriate
230255 if ( datatype === '@json' ) {
231256 object . value = jsonCanonicalize ( value ) ;
@@ -244,6 +269,9 @@ function _objectToRDF(item, issuer, dataset, graphTerm) {
244269 object . value = value . toFixed ( 0 ) ;
245270 object . datatype . value = datatype || XSD_INTEGER ;
246271 } else if ( '@language' in item ) {
272+ if ( ! LANG_RE . test ( item [ '@language' ] ) ) {
273+ return null ;
274+ }
247275 object . value = value ;
248276 object . datatype . value = datatype || RDF_LANGSTRING ;
249277 object . language = item [ '@language' ] ;
@@ -258,6 +286,12 @@ function _objectToRDF(item, issuer, dataset, graphTerm) {
258286 } else {
259287 // convert string/node object to RDF
260288 const id = types . isObject ( item ) ? item [ '@id' ] : item ;
289+
290+ // invalid object IRI
291+ if ( ! IRIREF_RE . test ( id ) ) {
292+ return null ;
293+ }
294+
261295 object . termType = id . startsWith ( '_:' ) ? 'BlankNode' : 'NamedNode' ;
262296 object . value = id ;
263297 }
0 commit comments