Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Round-trip parsing and output generation causes difference in parsed result #165

Open
frewsxcv opened this issue Jun 25, 2017 · 3 comments

Comments

@frewsxcv
Copy link
Contributor

Found this while fuzzing.

extern crate cssparser;

use cssparser::ToCss;

fn main() {
    let input = "\\\n3:\'\\\x0c";
    println!("input:\n\t{:?}", input);

    let mut parser_input = cssparser::ParserInput::new(input);
    let mut parser = cssparser::Parser::new(&mut parser_input);
    let tokens = parser
        .next_including_whitespace_and_comments()
        .into_iter()
        .collect::<Vec<_>>();
    println!("tokens:\n\t{:?}", tokens);

    let str2 = tokens.iter().map(|t| t.to_css_string()).collect::<String>();
    println!("tokens to string:\n\t{:?}", str2);

    let mut parser_input = cssparser::ParserInput::new(&str2);
    let mut parser = cssparser::Parser::new(&mut parser_input);
    let tokens2 = parser
        .next_including_whitespace_and_comments()
        .into_iter()
        .collect::<Vec<_>>();
    println!("tokens to string to tokens:\n\t{:?}", tokens2);
}
input:
	"\\\n3:\'\\\u{c}"
tokens:
	[Delim('\\')]
tokens to string:
	"\\"
tokens to string to tokens:
	[Ident("�")]
@SimonSapin
Copy link
Member

I was surprised to see only one token. This is because you only call next* once, and the into_iter call is a method of Result. You likely want something like:

    let mut tokens = Vec::new();
    while let Ok(token) = parser.next_including_whitespace_and_comments() {
        tokens.push(token)
    }

… and similarly for tokens2. This makes assert_eq!(tokens, tokens2); pass.

@frewsxcv
Copy link
Contributor Author

Blah, you're right. I fixed that and here's a new issue:

extern crate cssparser;

use cssparser::ToCss;

fn main() {
    let input = "/~*3E833";
    println!("input:\n\t{:?}", input);

    let mut parser_input = cssparser::ParserInput::new(input);
    let mut parser = cssparser::Parser::new(&mut parser_input);
    let mut tokens = vec![];
    while let Ok(token) = parser.next_including_whitespace_and_comments() {
        tokens.push(token)
    }
    println!("tokens:\n\t{:?}", tokens);

    let str2 = tokens.iter().map(|t| t.to_css_string()).collect::<String>();
    println!("tokens to string:\n\t{:?}", str2);

    let mut parser_input = cssparser::ParserInput::new(&str2);
    let mut parser = cssparser::Parser::new(&mut parser_input);
    let mut tokens2 = vec![];
    while let Ok(token) = parser.next_including_whitespace_and_comments() {
        tokens2.push(token)
    }
    println!("tokens to string to tokens:\n\t{:?}", tokens2);
}
input:
	"/~*3E833"
tokens:
	[Delim('/'), Delim('~'), Delim('*'), Number { has_sign: false, value: inf, int_value: None }]
tokens to string:
	"/~*inf"
tokens to string to tokens:
	[Delim('/'), Delim('~'), Delim('*'), Ident("inf")]

Looks like it's struggling with big numbers

bors bot added a commit to rust-fuzz/targets that referenced this issue Jun 27, 2017
80: Fix cssparser read-write-read target to iterate correctly. r=killercup

servo/rust-cssparser#165 (comment)
@SimonSapin
Copy link
Member

I’ve filed #167. If you want to keep fuzzing in the meantime, consider skipping cases where the serialization contains inf.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants