Skip to content

Commit

Permalink
fix: Replace double quotes in all property values
Browse files Browse the repository at this point in the history
  • Loading branch information
Stranger6667 committed Dec 4, 2023
1 parent c4749b3 commit 643fcb8
Show file tree
Hide file tree
Showing 7 changed files with 72 additions and 19 deletions.
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

0 comments on commit 643fcb8

Please sign in to comment.