Permalink
Browse files

Relax CSS inlining charset check to always permit ASCII-only data.

Needed for fonts.g.c due to apparent recent changes (and us not
permitting inlining there was making the corresponding continuous tests
fail).
  • Loading branch information...
morlovich authored and jeffkaufman committed Mar 4, 2016
1 parent 2bd239d commit e3aa7b78c584d7c98d3a18528f91a00bc62908a1
Showing with 39 additions and 7 deletions.
  1. +24 −5 net/instaweb/rewriter/css_inline_filter.cc
  2. +15 −2 net/instaweb/rewriter/css_inline_filter_test.cc
@@ -175,15 +175,34 @@ bool CssInlineFilter::ShouldInline(const ResourcePtr& resource,
return false;
}

// If the charset is incompatible with the HTML's, don't inline.
// If the charset is incompatible with the HTML's, we may not be able to
// inline.
StringPiece htmls_charset(driver()->containing_charset());
GoogleString css_charset = RewriteFilter::GetCharsetForStylesheet(
resource.get(), attrs_charset, htmls_charset);
if (!StringCaseEqual(htmls_charset, css_charset)) {
*reason = StrCat("CSS not inlined due to apparent charset incompatibility;"
" we think the HTML is ", htmls_charset,
" while the CSS is ", css_charset);
return false;
// Check if everything is in <= 127 range, we may still be able to
// inline if it keeps to the ASCII subset (also potentially dropping the
// BOM, since we'll strip it anyway).
StringPiece contents = resource->ExtractUncompressedContents();
StringPiece clean_contents(contents);
StripUtf8Bom(&clean_contents);

bool has_non_ascii = false;
for (int i = 0, n = clean_contents.size(); i < n; ++i) {
if (static_cast<unsigned char>(clean_contents[i]) >= 0x80) {
has_non_ascii = true;
break;
}
}

if (has_non_ascii) {
*reason = StrCat(
"CSS not inlined due to apparent charset incompatibility;"
" we think the HTML is ", htmls_charset,
" while the CSS is ", css_charset);
return false;
}
}

return true;
@@ -581,8 +581,8 @@ TEST_F(CssInlineFilterTest, InlineWithCompatibleBom) {
"", css_with_bom, true, css, "");
}

TEST_F(CssInlineFilterTest, DoNotInlineWithIncompatibleBom) {
const GoogleString css = "BODY { color: red; }\n";
TEST_F(CssInlineFilterTest, DoNotInlineWithIncompatibleBomAndNonAscii) {
const GoogleString css = "BODY { color: red; /* \xD2\x90 */ }\n";
const GoogleString css_with_bom = StrCat(kUtf8Bom, css);
TestInlineCssWithOutputUrl("http://www.example.com/index.html",
" <meta charset=\"ISO-8859-1\">\n",
@@ -594,6 +594,19 @@ TEST_F(CssInlineFilterTest, DoNotInlineWithIncompatibleBom) {
"while the CSS is utf-8");
}

TEST_F(CssInlineFilterTest, DoInlineWithIncompatibleBomAndAscii) {
// Even though the content is labeled utf-8, it keeps to ASCII subset, so it's
// safe to inline.
const GoogleString css = "BODY { color: red; }\n";
const GoogleString css_with_bom = StrCat(kUtf8Bom, css);
TestInlineCssWithOutputUrl("http://www.example.com/index.html",
" <meta charset=\"ISO-8859-1\">\n",
"http://www.example.com/styles.css",
"http://www.example.com/styles.css",
"", css_with_bom, true, css,
"");
}

// See: http://www.alistapart.com/articles/alternate/
// and http://www.w3.org/TR/html4/present/styles.html#h-14.3.1
TEST_F(CssInlineFilterTest, AlternateStylesheet) {

0 comments on commit e3aa7b7

Please sign in to comment.