Serializer: `write_escaped` is O(n²) when text doesn't contain `<`, `>` or `"`

オープン
#810 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 1 日以内に返信

まだ誰も着手していません。

評価

難易度
3/5
見積もり時間
1〜2日
初心者へのやさしさ
68/100
issue の種類
バグ
明瞭さ
明確に書かれている
活発さ
活発
技術スタック
rust
領域
performance

調査の方向性

Start in html5ever/src/serialize/mod.rs at HtmlSerializer::write_escaped, then build and run the html2html example with the reproduction in the issue. Compare timings as the input grows for &amp; and &nbsp; versus &amp;<; done means the problematic inputs no longer show the reported quadratic scaling.

索引モデルが issue の本文から書いたものです。

説明

HtmlSerializer::write_escaped finds the next byte to escape with two memchr searches (introduced by #740):

https://github.com/servo/html5ever/blob/6fcf956f59f54f0455464e6cd48fa4a69b9e8706/html5ever/src/serialize/mod.rs#L111-L114

If the text doesn't have an <, > or ", every & or non-breaking space will cause a full scan of the remaining text.

It's pretty common for text to contain &amp; and &nbsp; without <s or >s.

Repro using the html2html example:

cargo build --release -p markup5ever_rcdom --example html2html

TIMEFORMAT='%R s'

for text in '&amp;' '&amp;<' '&nbsp;'; do
  for count in 100000 200000 400000; do
    yes "$text" | head -n "$count" | tr -d '\n' > input.html
    echo -n "$text x $count: "
    time target/release/examples/html2html < input.html > /dev/null
  done
done

On a Linode G6 Dedicated machine with 2 vCPUs and 4 GB RAM, I get:

&amp; x 100000: 0.148 s
&amp; x 200000: 0.462 s
&amp; x 400000: 1.665 s
&amp;< x 100000: 0.096 s
&amp;< x 200000: 0.197 s
&amp;< x 400000: 0.376 s
&nbsp; x 100000: 0.241 s
&nbsp; x 200000: 0.839 s
&nbsp; x 400000: 3.492 s
主要言語
Rust
スター
2.6k
フォーク
299
平均マージ
8日 22時間
マージ済み PR(30日)
3

環境構築

このプロジェクトには開発コンテナ、Dockerfile、コントリビューションガイドがありません。まず README を読み、一般的な手順ははじめてのコントリビューションガイドを参照してください。

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

servo/html5ever のほかの issue

servo/html5ever の issue をすべて見る

似ている issue

Rust の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。