From dc0db358abe19481e475e10c32149b53370f1a1c Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Thu, 30 May 2024 05:57:31 +0200 Subject: Merging upstream version 1.72.1+dfsg1. Signed-off-by: Daniel Baumann --- vendor/mime/src/lib.rs | 9 ++++- vendor/mime/src/parse.rs | 93 +++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 100 insertions(+), 2 deletions(-) (limited to 'vendor/mime/src') diff --git a/vendor/mime/src/lib.rs b/vendor/mime/src/lib.rs index 1f24fb1cf..da1d3c0f6 100644 --- a/vendor/mime/src/lib.rs +++ b/vendor/mime/src/lib.rs @@ -23,7 +23,7 @@ //! } //! ``` -#![doc(html_root_url = "https://docs.rs/mime/0.3.16")] +#![doc(html_root_url = "https://docs.rs/mime/0.3.17")] #![deny(warnings)] #![deny(missing_docs)] #![deny(missing_debug_implementations)] @@ -47,6 +47,13 @@ pub struct Mime { params: ParamSource, } +/// An iterator of parsed mime +#[derive(Clone, Debug)] +pub struct MimeIter<'a> { + pos: usize, + source: &'a str, +} + /// A section of a `Mime`. /// /// For instance, for the Mime `image/svg+xml`, it contains 3 `Name`s, diff --git a/vendor/mime/src/parse.rs b/vendor/mime/src/parse.rs index d55e5494c..20022b775 100644 --- a/vendor/mime/src/parse.rs +++ b/vendor/mime/src/parse.rs @@ -5,7 +5,7 @@ use std::fmt; use std::iter::Enumerate; use std::str::Bytes; -use super::{Mime, Source, ParamSource, Indexed, CHARSET, UTF_8}; +use super::{Mime, MimeIter, Source, ParamSource, Indexed, CHARSET, UTF_8}; #[derive(Debug)] pub enum ParseError { @@ -49,6 +49,65 @@ impl Error for ParseError { } } +impl<'a> MimeIter<'a> { + /// A new iterator over mimes or media types + pub fn new(s: &'a str) -> Self { + Self { + pos: 0, + source: s, + } + } +} + +impl<'a> Iterator for MimeIter<'a> { + type Item = Result; + + fn next(&mut self) -> Option { + let start = self.pos; + let len = self.source.bytes().len(); + + if start >= len { + return None + } + + // Try parsing the whole remaining slice, until the end + match parse(&self.source[start ..len]) { + Ok(value) => { + self.pos = len; + Some(Ok(value)) + } + Err(ParseError::InvalidToken { pos, .. }) => { + // The first token is immediately found to be wrong by `parse`. Skip it + if pos == 0 { + self.pos += 1; + return self.next() + } + let slice = &self.source[start .. start + pos]; + // Try parsing the longest slice (until the first invalid token) + return match parse(slice) { + Ok(mime) => { + self.pos = start + pos + 1; + Some(Ok(mime)) + } + Err(_) => { + if start + pos < len { + // Skip this invalid slice, + // try parsing the remaining slice in the next iteration + self.pos = start + pos; + Some(Err(slice)) + } else { + None + } + } + } + } + // Do not process any other error condition: the slice is malformed and + // no character is found to be invalid: a character is missing + Err(_) => None, + } + } +} + pub fn parse(s: &str) -> Result { if s == "*/*" { return Ok(::STAR_STAR); @@ -361,3 +420,35 @@ fn test_lookup_tables() { assert_eq!(valid, should, "{:?} ({}) should be {}", i as char, i, should); } } + +#[test] +fn test_parse_iterator() { + let mut iter = MimeIter::new("application/json, application/json"); + assert_eq!(iter.next().unwrap().unwrap(), parse("application/json").unwrap()); + assert_eq!(iter.next().unwrap().unwrap(), parse("application/json").unwrap()); + assert_eq!(iter.next(), None); + + let mut iter = MimeIter::new("application/json"); + assert_eq!(iter.next().unwrap().unwrap(), parse("application/json").unwrap()); + assert_eq!(iter.next(), None); + + let mut iter = MimeIter::new("application/json; "); + assert_eq!(iter.next().unwrap().unwrap(), parse("application/json").unwrap()); + assert_eq!(iter.next(), None); +} + +#[test] +fn test_parse_iterator_invalid() { + let mut iter = MimeIter::new("application/json, invalid, application/json"); + assert_eq!(iter.next().unwrap().unwrap(), parse("application/json").unwrap()); + assert_eq!(iter.next().unwrap().unwrap_err(), "invalid"); + assert_eq!(iter.next().unwrap().unwrap(), parse("application/json").unwrap()); + assert_eq!(iter.next(), None); +} + +#[test] +fn test_parse_iterator_all_invalid() { + let mut iter = MimeIter::new("application/json, text/html"); + assert_eq!(iter.next().unwrap().unwrap_err(), "application/json"); + assert_eq!(iter.next(), None); +} -- cgit v1.2.3