Repository navigation
fix(instructor): fail closed on restructured feedback Html readback - #94
Conversation
Parse the readback Html with html.parser and accept only the structure the command sent: one attribute-free <p> holding text and attribute-free <br> line breaks. Whitespace outside the paragraph, a line break next to a tag, entity spelling, tag case and <br> spelling are tolerated; attributes such as hidden/style/class, other elements, comments, a second paragraph or any other raw line break now report unknown instead of saved-draft. Refs #91
|
This run was cancelled before it finished. |
|
ⓘ Qodo reviews are paused because your trial has ended. Ask your workspace admin to add credits to resume reviews. Manage billing |
|
Droid encountered an error —— View job |
[Medium impact] The PR appears safe to merge; no actionable issue was found in the changed code. SummaryThis PR makes feedback readback stricter.
Scope acknowledgment: Reviews (1) · Last reviewed commit: "fix(instructor): fail closed on restruct..." · Reviewed by Greptile |
html.parser drops invalid character references and end-tag junk, and the old comparison ignored outer line breaks, so <p>hello</p>, <p>hello</p hidden=x>, <p>he</>llo</p> and <p><br>hello<br><br></p> could still count as saved-draft. Check each tag's raw spelling, slice the text between tags from the source, decode it with a strict reference decoder, and compare line breaks exactly. Any parser error now means unknown.
|
Droid encountered an error —— View job |

Fixes the P1 from the #90 council (round 5, Terra) that was downgraded to P2 and merged even though the command did not fail closed.
Problem
After the draft-feedback POST,
_check_saved_commentchecked the readbackHtmlwith regexes that accepted<p …>with any attributes, treated</p><p …>as a line break, and treated a raw\nas a line break. SoHtml: "<p hidden>hello</p>"(orstyle=/class=, a second paragraph,<p>x\ny</p>, a trailing<p>) with a matchingTextreportedsaved-draft.Change
_html_textnow runs a stdlibhtml.parser.HTMLParser(convert_charrefs=True) and accepts only the structure the command sends: whitespace, then one<p>with no attributes holding only text and attribute-free<br>, then</p>, then whitespace.<p>/<br>/</p>, entity spelling (&/&/&,"vs", …), tag case, and<br>/<br/>/<br />. NBSP counts as a space and outer line breaks are ignored, as before.<script>/<style>, comments, doctype, CDATA, PIs, a second or unclosed paragraph,</br>, an unfinished trailing tag, text after</p>, or any other raw line break) → mismatch →outcome: "unknown".docs/assignment-feedback.md.Tests
Textmatches:<p hidden>,<p style=…>,<p class=…>,<p id=…>,<br class=…>, span/div/img,<script>and<style>inside or after the paragraph, comments (also unfinished and bogus), doctype, CDATA, PI, a second paragraph (filled, empty or unclosed),<p/>, unclosed, no paragraph, a stray or double</p>,</br>, a trailing<b, text or an entity after</p>, a raw\ninside, two newlines after<br>.<br>spellings, tag case, spaces inside tags, outer whitespace, line breaks next to tags (LF and CRLF), entity spellings, raw<text, NBSP, a dropped trailing break._html_text(_html(t))round-trips for a set of tricky texts.<p hidden>with matchingText→ exit 1,outcome: unknown, neversaved-draft.paragraphsandattributes-nbspis replaced; both shapes are now rejected.Scope
Owner wrap-up: this PR only fixes the P1. The #91 items (cancel-document ids, Ctrl-C before the POST, published-warning ordering, "Nothing was sent." on pre-POST transport errors, broadening
_send, the duplicate method check inwrite(), TOCTOU, live shape) and the round-5 P3s that this change doesn't already fix stay open on #91. The parser fixes two of those round-5 P3s: a raw\ncounting as a line break, and an accepted trailing<p>.Refs #91
Gate (head 68df29e)
saved-draftshapes: end-tag junk, dropped invalid charrefs, and ignored outer line breaks. The check now validates raw tokens: it checks each tag's spelling, slices the text between tags from the source, decodes it with a strict reference decoder, and compares line breaks exactly.unknown. That fails closed, so it was lowered to P2 and filed in assignment-feedback: follow-ups from #94 reviews (fail-closed edges and tests) #95 with the P3s.droid-reviewfailed because Droid hit its usage limit; it isn't a required check.