diff options
| author | Charles Forsyth <charles.forsyth@gmail.com> | 2013-06-06 20:59:23 +0000 |
|---|---|---|
| committer | Charles Forsyth <charles.forsyth@gmail.com> | 2013-06-06 20:59:23 +0000 |
| commit | 72335078034e3cd7edcb1739556b405a3e1e9bf8 (patch) | |
| tree | 9e1baa8ea80bfab1885cfcf224a62040a417fa74 /libbio/bgetrune.c | |
| parent | 3a0400887de9df81e4d4fb3bc3dec52af2d49f80 (diff) | |
sync with plan 9
Diffstat (limited to 'libbio/bgetrune.c')
| -rw-r--r-- | libbio/bgetrune.c | 16 |
1 files changed, 11 insertions, 5 deletions
diff --git a/libbio/bgetrune.c b/libbio/bgetrune.c index ed216379..13b02bec 100644 --- a/libbio/bgetrune.c +++ b/libbio/bgetrune.c @@ -6,7 +6,7 @@ Bgetrune(Biobuf *bp) { int c, i; Rune rune; - char str[4]; + char str[UTFmax]; c = Bgetc(bp); if(c < Runeself) { /* one char */ @@ -14,19 +14,25 @@ Bgetrune(Biobuf *bp) return c; } str[0] = c; + bp->runesize = 0; for(i=1;;) { c = Bgetc(bp); if(c < 0) return c; + if (i >= sizeof str) + return Runeerror; str[i++] = c; if(fullrune(str, i)) { + /* utf is long enough to be a rune, but could be bad. */ bp->runesize = chartorune(&rune, str); - while(i > bp->runesize) { - Bungetc(bp); - i--; - } + if (rune == Runeerror) + bp->runesize = 0; /* push back nothing */ + else + /* push back bytes unconsumed by chartorune */ + for(; i > bp->runesize; i--) + Bungetc(bp); return rune; } } |
