@@ -544,7 +544,11 @@ public static string Escape(string str)
544544
545545 private class Regex
546546 {
547- public static readonly Pattern Iri = Pattern . Compile ( "(?:<([^>]*)>)" ) ;
547+ public static readonly Pattern HEX = Pattern . Compile ( "[0-9A-Fa-f]" ) ;
548+
549+ public static readonly Pattern UCHAR = Pattern . Compile ( "\\ \\ u" + HEX + "{4}|\\ \\ U" + HEX + "{8}" ) ;
550+
551+ public static readonly Pattern Iri = Pattern . Compile ( "(?:<((?:[^\\ x00-\\ x20<>\" {}|^`\\ \\ ]|" + UCHAR + ")*)>)" ) ;
548552
549553 public static readonly Pattern Bnode = Pattern . Compile ( "(_:(?:[A-Za-z0-9](?:[A-Za-z0-9\\ -\\ .]*[A-Za-z0-9])?))"
550554 ) ;
@@ -618,19 +622,25 @@ public static RDFDataset ParseNQuads(string input)
618622 RDFDataset . Node subject ;
619623 if ( match . Group ( 1 ) != null )
620624 {
621- subject = new RDFDataset . IRI ( Unescape ( match . Group ( 1 ) ) ) ;
625+ var subjectIri = Unescape ( match . Group ( 1 ) ) ;
626+ AssertAbsoluteIri ( subjectIri ) ;
627+ subject = new RDFDataset . IRI ( subjectIri ) ;
622628 }
623629 else
624630 {
625631 subject = new RDFDataset . BlankNode ( Unescape ( match . Group ( 2 ) ) ) ;
626632 }
627633 // get predicate
628- RDFDataset . Node predicate = new RDFDataset . IRI ( Unescape ( match . Group ( 3 ) ) ) ;
634+ var predicateIri = Unescape ( match . Group ( 3 ) ) ;
635+ AssertAbsoluteIri ( predicateIri ) ;
636+ RDFDataset . Node predicate = new RDFDataset . IRI ( predicateIri ) ;
629637 // get object
630638 RDFDataset . Node @object ;
631639 if ( match . Group ( 4 ) != null )
632640 {
633- @object = new RDFDataset . IRI ( Unescape ( match . Group ( 4 ) ) ) ;
641+ var objectIri = Unescape ( match . Group ( 4 ) ) ;
642+ AssertAbsoluteIri ( objectIri ) ;
643+ @object = new RDFDataset . IRI ( objectIri ) ;
634644 }
635645 else
636646 {
@@ -643,6 +653,7 @@ public static RDFDataset ParseNQuads(string input)
643653 string language = Unescape ( match . Group ( 8 ) ) ;
644654 string datatype = match . Group ( 7 ) != null ? Unescape ( match . Group ( 7 ) ) : match . Group
645655 ( 8 ) != null ? JSONLDConsts . RdfLangstring : JSONLDConsts . XsdString ;
656+ AssertAbsoluteIri ( datatype ) ;
646657 string unescaped = Unescape ( match . Group ( 6 ) ) ;
647658 @object = new RDFDataset . Literal ( unescaped , datatype , language ) ;
648659 }
@@ -652,6 +663,7 @@ public static RDFDataset ParseNQuads(string input)
652663 if ( match . Group ( 9 ) != null )
653664 {
654665 name = Unescape ( match . Group ( 9 ) ) ;
666+ AssertAbsoluteIri ( name ) ;
655667 }
656668 else
657669 {
@@ -680,5 +692,13 @@ public static RDFDataset ParseNQuads(string input)
680692 }
681693 return dataset ;
682694 }
695+
696+ private static void AssertAbsoluteIri ( string iri )
697+ {
698+ if ( Uri . IsWellFormedUriString ( Uri . EscapeUriString ( iri ) , UriKind . Absolute ) == false )
699+ {
700+ throw new JsonLdError ( JsonLdError . Error . SyntaxError , "Invalid absolute URI <" + iri + ">" ) ;
701+ }
702+ }
683703 }
684704}
0 commit comments