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

fix: Replace double quotes in all property values #271

Merged
merged 1 commit into from
Dec 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@
- Update `selectors` to `0.25`.
- Bump MSRV to `1.65`.

### Fixed

- Replace double quotes in all property values.

### Performance

- Avoid allocation when replacing double quotes in property values.

## [0.11.0] - 2023-09-26

### Added
Expand Down
4 changes: 4 additions & 0 deletions benchmarks/benchmarks.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
"name": "merging",
"html": "<html><head><style>h1, h2 { color:blue; }strong { text-decoration:none }p { font-size:2px }p.footer { font-size: 1px}</style></head><body><h1 style=\"background-color: black;\">Big Text</h1><p style=\"background-color: black;\"><strong style=\"background-color: black;\">Solid</strong></p><p class=\"footer\" style=\"background-color: black;\">Foot notes</p></body></html>"
},
{
"name": "double_quotes",
"html": "<html><head><style>h1 { --bs-font-sans-serif: system-ui, -apple-system, \"Segoe UI\", Roboto, \"Helvetica Neue\", Arial, \"Noto Sans\", \"Liberation Sans\", sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\", \"Noto Color Emoji\"; --bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace; }</style></head><body><h1>Big Text</h1><h1>Big Text</h1><h1>Big Text</h1><h1>Big Text</h1><h1>Big Text</h1><h1>Big Text</h1><h1>Big Text</h1><h1>Big Text</h1><h1>Big Text</h1></body></html>"
},
{
"name": "big_email_1",
"html": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"><html><head><title>Newsletter</title><meta name=\"viewport\" content=\"width = 620\" /><style type=\"text/css\">img {margin:0}a.bluelink:link,a.bluelink:visited,a.bluelink:active {color:#5b7ab3; text-decoration: none}a.bluelink:hover {color:#5b7ab3; text-decoration: underline}</style><style media=\"only screen and (max-device-width: 480px)\" type=\"text/css\">* {line-height: normal !important; -webkit-text-size-adjust: 125%}</style></head><body bgcolor=\"#FFFFFF\" style=\"margin:0; padding:0\"><table width=\"100%\" bgcolor=\"#FFFFFF\" cellpadding=\"0\" cellspacing=\"0\" align=\"center\" border=\"2\"><tr><td style=\"padding: 30px\"><!----><table width=\"636\" border=\"0\" cellspacing=\"0\" cellpadding=\"0\" align=\"center\"><tr><td width=\"636\"><img src=\"http://images.apple.com/data/retail/us/topcap.gif\" border=\"0\" alt=\"\" width=\"636\" height=\"62\" style=\"display:block\" /></td></tr></table><!----><table width=\"636\" border=\"1\" cellspacing=\"0\" cellpadding=\"0\" align=\"center\" bgcolor=\"#fffef6\"><tr><td width=\"59\" valign=\"top\" background=\"http://images.apple.com/data/retail/us/leftbg.gif\"><img src=\"http://images.apple.com/data/retail/us/leftcap.gif\" width=\"59\" height=\"302\" border=\"1\" alt=\"\" style=\"display:block\" /></td><td width=\"500\" align=\"left\" valign=\"top\"><!----><table width=\"500\" border=\"1\" cellspacing=\"0\" cellpadding=\"0\"><tr><td width=\"379\" align=\"left\" valign=\"top\"><div><img src=\"http://images.apple.com/data/retail/us/headline.gif\" width=\"330\" height=\"29\" border=\"1\" alt=\"Thanks for making a reservation.\" style=\"display:block\" /></div></td><td width=\"21\" align=\"right\" valign=\"top\"><div><img src=\"http://images.apple.com/data/retail/us/applelogo.gif\" width=\"21\" height=\"25\" border=\"1\" alt=\"\" style=\"display:block\" /></div></td></tr></table><!----><table width=\"500\" border=\"1\" cellspacing=\"0\" cellpadding=\"0\"><tr><td width=\"500\" align=\"left\" valign=\"top\"><div><img src=\"http://images.apple.com/data/retail/us/line.gif\" width=\"500\" height=\"36\" border=\"0\" alt=\"\" style=\"display:block\" /></div></td></tr></table><!----><table width=\"500\" border=\"1\" cellspacing=\"0\" cellpadding=\"0\"><tr><td width=\"10\" align=\"left\" valign=\"top\"></td><td width=\"340\" align=\"left\" valign=\"top\"><div style=\"margin: 0; padding: 2px 10px 0 0; font-family: Lucida Grande, Arial, Helvetica, Geneva, Verdana, sans-serif; color: #000000 !important; font-size:12px; line-height: 16px\">Dear peter,</div><div style=\"margin: 0; padding: 12px 10px 0 0; font-family: Lucida Grande, Arial, Helvetica, Geneva, Verdana, sans-serif; color: #000000 !important; font-size:12px; line-height: 16px\">You are scheduled for a Genius Bar appointment.</div><div style=\"margin: 0; padding: 12px 10px 0 0; font-family: Lucida Grande, Arial, Helvetica, Geneva, Verdana, sans-serif; color: #000000 !important; font-size:12px; line-height: 16px\">Topic: <b>iPhone</b></div><div style=\"margin: 0; padding: 12px 10px 0 0; font-family: Lucida Grande, Arial, Helvetica, Geneva, Verdana, sans-serif; color: #000000 !important; font-size:12px; line-height: 16px\">Date: <b>Wednesday, Aug 26, 2009</b></div><div style=\"margin: 0; padding: 12px 10px 0 0; font-family: Lucida Grande, Arial, Helvetica, Geneva, Verdana, sans-serif; color: #000000 !important; font-size:12px; line-height: 16px\">Time: <b>11:10AM</b></div><div style=\"margin: 0; padding: 12px 10px 0 0; font-family: Lucida Grande, Arial, Helvetica, Geneva, Verdana, sans-serif; color: #000000 !important; font-size:12px; line-height: 16px\">Location: <b>Apple Store, Regent Street</b></div></td><td width=\"150\" align=\"left\" valign=\"top\"><div style=\"margin: 0; padding: 2px 0 0 0; font-family: Lucida Grande, Arial, Helvetica, Geneva, Verdana, sans-serif; color:#808285; font-size:11px; line-height: 13px\">Apple Store,</div><div style=\"margin: 0; padding: 0 0 0 0; font-family: Lucida Grande, Arial, Helvetica, Geneva, Verdana, sans-serif; color:#808285; font-size:11px; line-height: 13px\">Regent Street</div><div style=\"margin: 0; padding: 7px 0 0 0; font-family: Lucida Grande, Arial, Helvetica, Geneva, Verdana, sans-serif; color:#808285; font-size:11px; line-height: 13px\"><a href=\"http://concierge.apple.com/WebObjects/RRSServices.woa/wa/ics?id=ewoJInByaW1hcnlLZXkiID0gewoJCSJyZXNlcnZhdGlvbklEIiA9ICI1ODEyMDI2NCI7Cgl9OwoJImVudGl0eU5hbWUiID0gIlJlc2VydmF0aW9uIjsKfQ%3D%3D\" style=\"font-family: Lucida Grande, Arial, Helvetica, Geneva, Verdana, sans-serif; font-size:11px; color:#5b7ab3\" class=\"bluelink\">Add this to your calendar<img src=\"http://images.apple.com/data/retail/us/bluearrow.gif\" width=\"8\" height=\"8\" border=\"0\" alt=\"\" style=\"display:inline; margin:0\" /></a></div><div style=\"margin: 0; padding: 7px 0 0 0; font-family: Lucida Grande, Arial, Helvetica, Geneva, Verdana, sans-serif; color:#808285; font-size:11px; line-height: 13px\">If you are no longer able to attend this session, please <a href=\"http://concierge.apple.com/WebObjects/Concierge.woa/wa/cancelReservation?r=ewoJInByaW1hcnlLZXkiID0gewoJCSJyZXNlcnZhdGlvbklEIiA9ICI1ODEyMDI2NCI7Cgl9OwoJImVudGl0eU5hbWUiID0gIlJlc2VydmF0aW9uIjsKfQ%3D%3D\" style=\"font-family: Lucida Grande, Arial, Helvetica, Geneva, Verdana, sans-serif; font-size:11px; color:#5b7ab3\" class=\"bluelink\">cancel</a> or <a href=\"http://concierge.apple.com/WebObjects/Concierge.woa/wa/cancelReservation?r=ewoJInByaW1hcnlLZXkiID0gewoJCSJyZXNlcnZhdGlvbklEIiA9ICI1ODEyMDI2NCI7Cgl9OwoJImVudGl0eU5hbWUiID0gIlJlc2VydmF0aW9uIjsKfQ%3D%3D\" style=\"font-family: Lucida Grande, Arial, Helvetica, Geneva, Verdana, sans-serif; font-size:11px; color:#5b7ab3\" class=\"bluelink\">reschedule</a> your reservation.</div><div style=\"margin: 0; padding: 7px 0 0 0; font-family: Lucida Grande, Arial, Helvetica, Geneva, Verdana, sans-serif; color:#808285; font-size:11px; line-height: 13px\"><a href=\"http://www.apple.com/retail/../uk/retail/regentstreet/map\" style=\"font-family: Lucida Grande, Arial, Helvetica, Geneva, Verdana, sans-serif; font-size:11px; color:#5b7ab3\" class=\"bluelink\">Get directions to the store<img src=\"http://images.apple.com/data/retail/us/bluearrow.gif\" width=\"8\" height=\"8\" border=\"0\" alt=\"\" style=\"display:inline; margin:0\" /></a></div></td></tr></table><!----><table width=\"500\" border=\"1\" cellspacing=\"0\" cellpadding=\"0\"><tr><td width=\"10\"></td><td width=\"490\" align=\"left\" valign=\"top\"><br><div style=\"margin: 0; padding: 0 20px 0 0; font-family: Lucida Grande, Arial, Helvetica, Geneva, Verdana, sans-serif; color: #000000 !important; font-size:12px; line-height: 16px\">We look forward to seeing you.</div><div style=\"margin: 0; padding: 0 20px 0 0; font-family: Lucida Grande, Arial, Helvetica, Geneva, Verdana, sans-serif; color: #000000 !important; font-size:12px; line-height: 16px\">Your Apple Store team,</div><div style=\"margin: 0; padding: 0 20px 0 0; font-family: Lucida Grande, Arial, Helvetica, Geneva, Verdana, sans-serif; color: #000000 !important; font-size:12px; line-height: 16px\">Regent Street</div></td></tr></table><!----></td><td width=\"59\" valign=\"top\" background=\"http://images.apple.com/data/retail/us/rightbg.gif\"><img src=\"http://images.apple.com/data/retail/us/rightcap.gif\" width=\"77\" height=\"302\" border=\"0\" alt=\"\" style=\"display:block\" /></td></tr></table><!----><table width=\"636\" border=\"1\" cellspacing=\"0\" cellpadding=\"0\" align=\"center\"><tr><td width=\"636\"><img src=\"http://images.apple.com/data/retail/us/bottomcap.gif\" border=\"0\" alt=\"\" width=\"636\" height=\"62\" style=\"display:block\" /></td></tr></table><!--BEGIN FOOTER--><table width=\"498\" border=\"1\" cellspacing=\"0\" cellpadding=\"0\" align=\"center\"><tr><td style=\"padding-top:22px\"><div style=\"font-family: Geneva, Verdana, Arial, Helvetica, sans-serif; font-size:9px; line-height: 12px; color:#b4b4b4\">TM and copyright &copy; 2008 Apple Inc. 1 Infinite Loop, MS 303-3DM, Cupertino, CA 95014.</div><div style=\"font-family: Geneva, Verdana, Arial, Helvetica, sans-serif; font-size:9px; line-height: 12px; color:#b4b4b4\"><a href=\"http://www.apple.com/legal/\" style=\"font-family: Geneva, Verdana, Arial, Helvetica, sans-serif; font-size:9px;line-height: 12px; color:#b4b4b4; text-decoration:underline\">All Rights Reserved</a> / <a href=\"http://www.apple.com/enews/subscribe/\"style=\"font-family: Geneva, Verdana, Arial, Helvetica, sans-serif; font-size:9px; line-height: 12px;color:#b4b4b4; text-decoration:underline\">Keep Informed</a> / <a href=\"http://www.apple.com/legal/privacy/\" style=\"font-family: Geneva, Verdana, Arial, Helvetica, sans-serif; font-size:9px; line-height: 12px; color:#b4b4b4; text-decoration:underline\">Privacy Policy</a> / <a href=\"https://myinfo.apple.com/cgi-bin/WebObjects/MyInfo/\" style=\"font-family: Geneva, Verdana, Arial, Helvetica, sans-serif; font-size:9px; line-height: 12px; color:#b4b4b4; text-decoration:underline\">My Info</a></div></td></tr></table><!----></td></tr></table></body></html>"
Expand Down
8 changes: 8 additions & 0 deletions bindings/python/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@
- Update `selectors` to `0.25`.
- Bump MSRV to `1.65`.

### Fixed

- Replace double quotes in all property values.

### Performance

- Avoid allocation when replacing double quotes in property values.

## [0.11.0] - 2023-09-26

### Added
Expand Down
8 changes: 8 additions & 0 deletions bindings/ruby/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@
- Update `selectors` to `0.25`.
- Bump MSRV to `1.65`.

### Fixed

- Replace double quotes in all property values.

### Performance

- Avoid allocation when replacing double quotes in property values.

## [0.11.0] - 2023-09-26

### Added
Expand Down
13 changes: 9 additions & 4 deletions bindings/wasm/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,22 @@

## [Unreleased]

### Fixed

- `getrandom` dependency features.

### Changed

- Update `indexmap` to `2.1`.
- Update `cssparser` to `0.31.2`.
- Update `selectors` to `0.25`.
- Bump MSRV to `1.65`.

### Fixed

- `getrandom` dependency features.
- Replace double quotes in all property values.

### Performance

- Avoid allocation when replacing double quotes in property values.

## [0.11.0] - 2023-09-26

### Added
Expand Down
39 changes: 24 additions & 15 deletions css-inline/src/html/serializer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -366,20 +366,7 @@ impl<'a, W: Write> HtmlSerializer<'a, W> {
Ok(())
}
}
/// Replace double quotes in property values.
///
/// This implementation is deliberately simplistic and covers only `font-family`, but escaping
/// might be needed in other properties that accept strings.
macro_rules! replace_double_quotes {
($writer:expr, $name:expr, $value:expr) => {
// Avoid allocation if there is no double quote in the input string
if $name.starts_with("font-family") && $value.as_bytes().contains(&b'"') {
$writer.write_all(&$value.replace('"', "\'").as_bytes())?
} else {
$writer.write_all($value.as_bytes())?
};
};
}

const STYLE_SEPARATOR: &[u8] = b": ";

#[inline]
Expand All @@ -390,7 +377,29 @@ fn write_declaration<Wr: Write>(
) -> Result<(), InlineError> {
writer.write_all(name.as_bytes())?;
writer.write_all(STYLE_SEPARATOR)?;
replace_double_quotes!(writer, name, value.trim());
let value = value.trim();
if value.as_bytes().contains(&b'"') {
// Roughly based on `str::replace`
let mut last_end = 0;
for (start, part) in value.match_indices('"') {
writer.write_all(
value
.get(last_end..start)
.expect("Invalid substring")
.as_bytes(),
)?;
writer.write_all(b"'")?;
last_end = start.checked_add(part.len()).expect("Size overflow");
}
writer.write_all(
value
.get(last_end..value.len())
.expect("Invalid substring")
.as_bytes(),
)?;
} else {
writer.write_all(value.as_bytes())?;
};
Ok(())
}

Expand Down
11 changes: 11 additions & 0 deletions css-inline/tests/test_inlining.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,17 @@ fn font_family_quoted() {
)
}

#[test]
fn other_property_quoted() {
// When property value contains double quotes
assert_inlined!(
style = r#"h1 { --bs-font-sant-serif: system-ui,-applie-system,"helvetica neue"; }"#,
body = r#"<h1>Hello world!</h1>"#,
// Then it should be replaced with single quotes
expected = r#"<h1 style="--bs-font-sant-serif: system-ui,-applie-system,'helvetica neue';">Hello world!</h1>"#
)
}

#[test]
fn href_attribute_unchanged() {
// All HTML attributes should be serialized as is
Expand Down