@@ -18,7 +18,7 @@ use crate::_cnq::nq;
18
18
use crate :: _permutations:: for_each_permutation_of;
19
19
use crate :: hash:: { HashFunction , Sha256 , Sha384 } ;
20
20
21
- /// Return a canonical N-quads representation of `d`, where
21
+ /// Write into `w` a canonical N-quads representation of `d`, where
22
22
/// + blank nodes are canonically [relabelled](`relabel`) with
23
23
/// - the [SHA-256](Sha256) hash function,
24
24
/// - the [`DEFAULT_DEPTH_FACTOR`],
@@ -30,8 +30,8 @@ pub fn normalize<D: Dataset, W: io::Write>(d: &D, w: W) -> Result<(), C14nError<
30
30
normalize_with :: < Sha256 , D , W > ( d, w, DEFAULT_DEPTH_FACTOR , DEFAULT_PERMUTATION_LIMIT )
31
31
}
32
32
33
- /// Return a canonical N-quads representation of `d`, where
34
- /// + blank nodes are canonically [relabelled](`relabel `) with
33
+ /// Write into `w` a canonical N-quads representation of `d`, where
34
+ /// + blank nodes are canonically [relabelled](`relabel_sha384 `) with
35
35
/// - the [SHA-384](Sha384) hash function,
36
36
/// - the [`DEFAULT_DEPTH_FACTOR`],
37
37
/// - the [`DEFAULT_PERMUTATION_LIMIT`];
@@ -42,8 +42,11 @@ pub fn normalize_sha384<D: Dataset, W: io::Write>(d: &D, w: W) -> Result<(), C14
42
42
normalize_with :: < Sha384 , D , W > ( d, w, DEFAULT_DEPTH_FACTOR , DEFAULT_PERMUTATION_LIMIT )
43
43
}
44
44
45
- /// Return a canonical N-quads representation of `d`, where
46
- /// - blank nodes are canonically [relabelled](`relabel_with`) with the given `depth_factor`,
45
+ /// Write into `w` a canonical N-quads representation of `d`, where
46
+ /// + blank nodes are canonically [relabelled](`relabel_with`) with
47
+ /// - the [hash function](HashFunction) `H`,
48
+ /// - the given `depth_factor`,
49
+ /// - the given `permutation_limit`;
47
50
/// - quads are sorted in codepoint order.
48
51
///
49
52
/// See also [`normalize`].
@@ -111,12 +114,24 @@ pub fn relabel_sha384<D: Dataset>(d: &D) -> Result<(C14nQuads<D>, C14nIdMap), C1
111
114
relabel_with :: < Sha384 , D > ( d, DEFAULT_DEPTH_FACTOR , DEFAULT_PERMUTATION_LIMIT )
112
115
}
113
116
114
- /// Return a [`Dataset`] isomorphic to `d`, with canonical blank node labels,
115
- /// restricting the number of recursion of RDFC-1.0 to `depth_factor` per blank node,
116
- /// and restricting the size of permutations to `permutation_limit`!.
117
+ /// Return a [`Dataset`] isomorphic to `d`, with canonical blank node labels.
118
+ ///
119
+ /// The generic parameter `H` determines which [hash function](HashFunction)
120
+ /// the algorithm should use internally
121
+ /// (RDFC-1.0 uses [SHA-256](Sha256) by default).
122
+ ///
123
+ /// The parameters `depth_factor` and `permutation_limit`
124
+ /// are used to stop the algorithm if the computation becomes too complex,
125
+ /// in order to secure it agains [dataset poisoning](https://www.w3.org/TR/rdf-canon/#dataset-poisoning).
126
+ /// The default values ([`DEFAULT_DEPTH_FACTOR`]) and [`DEFAULT_PERMUTATION_LIMIT`])
127
+ /// are expected to work with any "realistic" dataset.
117
128
///
118
- /// These restrictions prevents the algorithm from blocking on pathological graphs with little practical utility
119
- /// (e.g. big cycles or cliques of undistinguishable blank nodes).
129
+ /// More preciselity:
130
+ /// * the algorithm will not recurse more deeply than`depth_factor`*N,
131
+ /// where N is the total number of blank nodes in the dataset;
132
+ /// * the algorithl will not try to disambiguate more than
133
+ /// `permutation_limit` undistinguishable blank nodes
134
+ /// (blank nodes with the same immediate neighbourhood).
120
135
///
121
136
/// Implements <https://www.w3.org/TR/rdf-canon/#canon-algorithm>
122
137
///
@@ -133,6 +148,11 @@ pub fn relabel_with<'a, H: HashFunction, D: Dataset>(
133
148
let mut state = C14nState :: < H , _ > :: new ( depth_factor, permutation_limit) ;
134
149
// Step 2
135
150
for quad in & quads {
151
+ if quad. p ( ) . is_blank_node ( ) {
152
+ return Err ( C14nError :: Unsupported (
153
+ "RDFC-1.0 does not support blank node as predicate" . to_string ( ) ,
154
+ ) ) ;
155
+ }
136
156
for component in iter_spog ( quad. spog ( ) ) {
137
157
if component. is_triple ( ) || component. is_variable ( ) {
138
158
return Err ( C14nError :: Unsupported (
@@ -148,11 +168,6 @@ pub fn relabel_with<'a, H: HashFunction, D: Dataset>(
148
168
}
149
169
}
150
170
}
151
- if quad. p ( ) . is_blank_node ( ) {
152
- return Err ( C14nError :: Unsupported (
153
- "RDFC-1.0 does not support blank node as predicate" . to_string ( ) ,
154
- ) ) ;
155
- }
156
171
}
157
172
// Step 3
158
173
for ( bnid, quads) in state. b2q . iter ( ) {
0 commit comments