Hmm, I take that back. I couldn't reproduce this with plain libxml2 (i.e. their xmllint tool), so it must be something in lxml.
$ echo "<a><b><b></a>&foo" | xmllint --html --recover --noent -
-:1: HTML parser error : Opening and ending tag mismatch: a and b
<a><b><b></a>&foo
^
-:1: HTML parser error : Opening and ending tag mismatch: a and b
<a><b><b></a>&foo
^
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html><body>
<a><b><b></b></b></a>&foo
</body></html>
Hmm, I take that back. I couldn't reproduce this with plain libxml2 (i.e. their xmllint tool), so it must be something in lxml.
$ echo "<a><b> <b></a> &foo" | xmllint --html --recover --noent - b></a>& amp;foo b></a>& amp;foo www.w3. org/TR/ REC-html40/ loose.dtd"> b></b>< /b></a> &foo
-:1: HTML parser error : Opening and ending tag mismatch: a and b
<a><b><
^
-:1: HTML parser error : Opening and ending tag mismatch: a and b
<a><b><
^
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://
<html><body>
<a><b><
</body></html>