diff options
Diffstat (limited to 'lib/render/escape.ml')
| -rw-r--r-- | lib/render/escape.ml | 8 |
1 files changed, 8 insertions, 0 deletions
diff --git a/lib/render/escape.ml b/lib/render/escape.ml index 53fdd46..f506c44 100644 --- a/lib/render/escape.ml +++ b/lib/render/escape.ml @@ -77,6 +77,14 @@ let fold_ics line = else begin let cut = ref (pos + limit) in while !cut > pos && is_cont line.[!cut] do decr cut done; + (* Valid UTF-8's longest continuation run is 3, so backoff finds a + boundary within a few bytes. But this function must stay TOTAL on + ARBITRARY octet strings, not only valid UTF-8: 74+ consecutive + continuation bytes back `cut` all the way down to `pos`, which would + yield a zero-length chunk and recurse on the identical position + forever. When backoff finds no boundary inside the window, cut hard + at the limit instead -- forward progress is then unconditional. *) + if !cut = pos then cut := pos + limit; if not first then Buffer.add_char b ' '; Buffer.add_string b (String.sub line pos (!cut - pos)); Buffer.add_string b "\r\n"; |
