From 747cf5e859cd0f26c140c7687dca227f1e316781 Mon Sep 17 00:00:00 2001 From: John-Mark Bell Date: Mon, 23 May 2022 23:02:26 +0100 Subject: Parse/MQ: reject forbidden media-type identifiers "and" / "not" / "only" / "or" are forbidden, so must be rejected Add tests for these scenarios --- src/parse/mq.c | 55 ++++++++++++++++++++++-------- test/data/parse2/INDEX | 1 + test/data/parse2/dodgy-media-block.dat | 2 +- test/data/parse2/eof.dat | 30 ++++++++-------- test/data/parse2/mq.dat | 62 ++++++++++++++++++++++++++++++++++ test/dump.h | 4 ++- 6 files changed, 122 insertions(+), 32 deletions(-) create mode 100644 test/data/parse2/mq.dat diff --git a/src/parse/mq.c b/src/parse/mq.c index b0e47c3..dde2bbe 100644 --- a/src/parse/mq.c +++ b/src/parse/mq.c @@ -882,59 +882,80 @@ static css_error mq_parse_condition(lwc_string **strings, /** * Parse a media query type. */ -static uint64_t mq_parse_type(lwc_string **strings, lwc_string *type) +static css_error mq_parse_type(lwc_string **strings, lwc_string *type, + uint64_t *result) { bool match; + css_error error = CSS_OK; if (type == NULL) { - return CSS_MEDIA_ALL; + *result = CSS_MEDIA_ALL; } else if (lwc_string_caseless_isequal( type, strings[AURAL], &match) == lwc_error_ok && match) { - return CSS_MEDIA_AURAL; + *result = CSS_MEDIA_AURAL; } else if (lwc_string_caseless_isequal( type, strings[BRAILLE], &match) == lwc_error_ok && match) { - return CSS_MEDIA_BRAILLE; + *result = CSS_MEDIA_BRAILLE; } else if (lwc_string_caseless_isequal( type, strings[EMBOSSED], &match) == lwc_error_ok && match) { - return CSS_MEDIA_EMBOSSED; + *result = CSS_MEDIA_EMBOSSED; } else if (lwc_string_caseless_isequal( type, strings[HANDHELD], &match) == lwc_error_ok && match) { - return CSS_MEDIA_HANDHELD; + *result = CSS_MEDIA_HANDHELD; } else if (lwc_string_caseless_isequal( type, strings[PRINT], &match) == lwc_error_ok && match) { - return CSS_MEDIA_PRINT; + *result = CSS_MEDIA_PRINT; } else if (lwc_string_caseless_isequal( type, strings[PROJECTION], &match) == lwc_error_ok && match) { - return CSS_MEDIA_PROJECTION; + *result = CSS_MEDIA_PROJECTION; } else if (lwc_string_caseless_isequal( type, strings[SCREEN], &match) == lwc_error_ok && match) { - return CSS_MEDIA_SCREEN; + *result = CSS_MEDIA_SCREEN; } else if (lwc_string_caseless_isequal( type, strings[SPEECH], &match) == lwc_error_ok && match) { - return CSS_MEDIA_SPEECH; + *result = CSS_MEDIA_SPEECH; } else if (lwc_string_caseless_isequal( type, strings[TTY], &match) == lwc_error_ok && match) { - return CSS_MEDIA_TTY; + *result = CSS_MEDIA_TTY; } else if (lwc_string_caseless_isequal( type, strings[TV], &match) == lwc_error_ok && match) { - return CSS_MEDIA_TV; + *result = CSS_MEDIA_TV; } else if (lwc_string_caseless_isequal( type, strings[ALL], &match) == lwc_error_ok && match) { - return CSS_MEDIA_ALL; + *result = CSS_MEDIA_ALL; + } else if (lwc_string_caseless_isequal( + type, strings[NOT], + &match) == lwc_error_ok && match) { + error = CSS_INVALID; + } else if (lwc_string_caseless_isequal( + type, strings[AND], + &match) == lwc_error_ok && match) { + error = CSS_INVALID; + } else if (lwc_string_caseless_isequal( + type, strings[OR], + &match) == lwc_error_ok && match) { + error = CSS_INVALID; + } else if (lwc_string_caseless_isequal( + type, strings[ONLY], + &match) == lwc_error_ok && match) { + error = CSS_INVALID; + } else { + /* Unknown type: same as not matching */ + *result = 0; } - return 0; + return error; } static css_error mq_parse_media_query(lwc_string **strings, @@ -1016,7 +1037,11 @@ static css_error mq_parse_media_query(lwc_string **strings, return CSS_INVALID; } - result->type = mq_parse_type(strings, token->idata); + error = mq_parse_type(strings, token->idata, &result->type); + if (error != CSS_OK) { + free(result); + return error; + } consumeWhitespace(vector, ctx); diff --git a/test/data/parse2/INDEX b/test/data/parse2/INDEX index 331cf5c..e4a369c 100644 --- a/test/data/parse2/INDEX +++ b/test/data/parse2/INDEX @@ -16,6 +16,7 @@ border.dat Border property tests font.dat Font property tests list.dat List property tests margin.dat Margin property tests +mq.dat Media queries outline.dat Outline property tests overflow.dat Overflow property tests padding.dat Padding property tests diff --git a/test/data/parse2/dodgy-media-block.dat b/test/data/parse2/dodgy-media-block.dat index 61179c3..4b6c220 100644 --- a/test/data/parse2/dodgy-media-block.dat +++ b/test/data/parse2/dodgy-media-block.dat @@ -2,7 +2,7 @@ @media only screen { dodgy } .outer { top: 0px } #errors #expected -| @media +| @media 040 | dodgy | .outer | top: 0px diff --git a/test/data/parse2/eof.dat b/test/data/parse2/eof.dat index 2f238d7..7fc4ab7 100644 --- a/test/data/parse2/eof.dat +++ b/test/data/parse2/eof.dat @@ -180,49 +180,49 @@ f{clear:both} @media screen #errors #expected -| @media +| @media 040 #reset #data @media screen #errors #expected -| @media +| @media 040 #reset #data @media screen{ #errors #expected -| @media +| @media 040 #reset #data @media screen{ #errors #expected -| @media +| @media 040 #reset #data @media screen{{ #errors #expected -| @media +| @media 040 #reset #data @media screen{; #errors #expected -| @media +| @media 040 #reset #data @media screen{f #errors #expected -| @media +| @media 040 | f #reset @@ -230,7 +230,7 @@ f{clear:both} @media screen{f{ #errors #expected -| @media +| @media 040 | f #reset @@ -238,7 +238,7 @@ f{clear:both} @media screen{f{color #errors #expected -| @media +| @media 040 | f #reset @@ -246,7 +246,7 @@ f{clear:both} @media screen{f{color: #errors #expected -| @media +| @media 040 | f #reset @@ -254,7 +254,7 @@ f{clear:both} @media screen{f{color:blue #errors #expected -| @media +| @media 040 | f | color: #ff0000ff #reset @@ -263,7 +263,7 @@ f{clear:both} @media screen{f{color:blue; #errors #expected -| @media +| @media 040 | f | color: #ff0000ff #reset @@ -272,7 +272,7 @@ f{clear:both} @media screen{f{color:blue} #errors #expected -| @media +| @media 040 | f | color: #ff0000ff #reset @@ -281,7 +281,7 @@ f{clear:both} @media screen{f{color:blue;} #errors #expected -| @media +| @media 040 | f | color: #ff0000ff #reset @@ -290,7 +290,7 @@ f{clear:both} @media screen{f{color:blue;}} #errors #expected -| @media +| @media 040 | f | color: #ff0000ff #reset diff --git a/test/data/parse2/mq.dat b/test/data/parse2/mq.dat new file mode 100644 index 0000000..56f0833 --- /dev/null +++ b/test/data/parse2/mq.dat @@ -0,0 +1,62 @@ +#data +@media not +#errors +#expected +| @media not 3ff +#reset + +#data +@media and +#errors +#expected +| @media not 3ff +#reset + +#data +@media or +#errors +#expected +| @media not 3ff +#reset + +#data +@media only +#errors +#expected +| @media not 3ff +#reset + +#data +@media only not +#errors +#expected +| @media not 3ff +#reset + +#data +@media only only +#errors +#expected +| @media not 3ff +#reset + +#data +@media not not +#errors +#expected +| @media not 3ff +#reset + +#data +@media not only +#errors +#expected +| @media not 3ff +#reset + +#data +@media screen +#errors +#expected +| @media 040 +#reset diff --git a/test/dump.h b/test/dump.h index 79819e0..acfd8b0 100644 --- a/test/dump.h +++ b/test/dump.h @@ -131,7 +131,9 @@ void dump_rule_media(css_rule_media *s, char **buf, size_t *buflen) char *ptr = *buf; css_rule *rule; - ptr += sprintf(ptr, "| @media "); + ptr += sprintf(ptr, "| @media %s%03lx", + s->media->negate_type ? "not " : "", + s->media->type); /* \todo media list */ -- cgit v1.2.3