Jakie są konteksty ucieczki HTML?

Podczas wysyłania kodu HTML istnieje kilka różnych miejsc, w których tekst może być interpretowany jako znaki sterujące, a nie jako literały tekstowe. Na przykład w „zwykłym” tekście (to znaczy poza dowolnym znacznikiem elementu):

<div>This is regular text</div>

Podobnie jak w przypadku wartości atrybutów:

<input value="this is value text">

I wierzę, że w komentarzach HTML:

<!-- This text here might be programmatically generated
and could, in theory, contain the double-hyphen character
sequence, which is verboten inside comments -->

Każdy z tych trzech rodzajów tekstu maróżne zasady dotyczące tego, jak należy go wydostać, aby można go było traktować jako nieuprawiane. Moje pierwsze pytanie brzmi: czy są jakieś inne konteksty w HTML, w których znaki mogą być interpretowane jako znaki znaczników / kontroli? Powyższe konteksty wyraźnie mają różne zasady dotyczące tego, czego należy unikać.

Drugie pytanie brzmi: jakie są kanoniczne, globalnie bezpieczne listy znaków (dla każdego kontekstu), które muszą być ucieczkowe, aby zapewnić, że każdy osadzony tekst jest traktowany jako nieoznaczony? Na przykład, teoretycznie wystarczy uciec „i” w wartościach atrybutów, ponieważw ramach wartości atrybutu tylko znak ogranicznika zamykającego („lub” w zależności od tego, który ogranicznik rozpoczął wartość atrybutu) miałby znaczenie kontrolne. Podobnie, tylko w „zwykłym” tekście <i i ma znaczenie kontrolne. (Zdaję sobie sprawę, że nie wszystkie parsery HTML są identyczne . Interesuje mnie przede wszystkim, jaki jest minimalny zestaw znaków, które wymagają ucieczki, aby uspokoić parser zgodny ze specyfikacją.)

Stycznie: Poniższy tekst rzuci błędy jako HTML 4.01 Strict:

<a href="http://example.com/file.php?x=1&y=2">foo</a>

Mówi w szczególności, że nie wie, czym powinna być jednostka „i y”. Jeśli umieścisz spację po &, to jednak sprawdzi się dobrze. Ale jeśli generujesz to w locie, prawdopodobnie nie będziesz chciał sprawdzać, czy każde użycie & spowoduje błąd sprawdzania poprawności, a zamiast tego po prostu uciec od wszystkich i wewnątrz wartości atrybutów.

questionAnswers(5)

yourAnswerToTheQuestion