| 1361 | } |
| 1362 | |
| 1363 | const fn validate_bytes(bytes: &[u8], offset: usize) -> Result<(), ParseError> { |
| 1364 | if bytes[0] != b'/' && offset == 0 { |
| 1365 | return Err(ParseError::NoLeadingSlash); |
| 1366 | } |
| 1367 | |
| 1368 | let mut ptr_offset = offset; // offset within the pointer of the most recent '/' separator |
| 1369 | let mut tok_offset = 0; // offset within the current token |
| 1370 | |
| 1371 | let mut i = offset; |
| 1372 | while i < bytes.len() { |
| 1373 | match bytes[i] { |
| 1374 | b'/' => { |
| 1375 | ptr_offset = i; |
| 1376 | // and reset the token offset |
| 1377 | tok_offset = 0; |
| 1378 | } |
| 1379 | b'~' => { |
| 1380 | // if the character is a '~', then the next character must be '0' or '1' |
| 1381 | // otherwise the encoding is invalid and `InvalidEncodingError` is returned |
| 1382 | if i + 1 >= bytes.len() || (bytes[i + 1] != b'0' && bytes[i + 1] != b'1') { |
| 1383 | // the pointer is not properly encoded |
| 1384 | // |
| 1385 | // we use the pointer offset, which points to the last |
| 1386 | // encountered separator, as the offset of the error. |
| 1387 | // The source `InvalidEncodingError` then uses the token |
| 1388 | // offset. |
| 1389 | // |
| 1390 | // "/foo/invalid~encoding" |
| 1391 | // ^ ^ |
| 1392 | // | | |
| 1393 | // ptr_offset | |
| 1394 | // tok_offset |
| 1395 | // |
| 1396 | return Err(ParseError::InvalidEncoding { |
| 1397 | offset: ptr_offset, |
| 1398 | source: EncodingError { |
| 1399 | offset: tok_offset, |
| 1400 | source: InvalidEncoding::Tilde, |
| 1401 | }, |
| 1402 | }); |
| 1403 | } |
| 1404 | // already checked the next character, so we skip it |
| 1405 | i += 1; |
| 1406 | // incrementing the pointer offset since the next byte has |
| 1407 | // already been checked |
| 1408 | tok_offset += 1; |
| 1409 | } |
| 1410 | _ => {} |
| 1411 | } |
| 1412 | i += 1; |
| 1413 | // not a separator so we increment the token offset |
| 1414 | tok_offset += 1; |
| 1415 | } |
| 1416 | Ok(()) |
| 1417 | } |
| 1418 | |
| 1419 | #[cfg(test)] |
| 1420 | mod tests { |