diff options
Diffstat (limited to 'libgo/runtime/go-rune.c')
-rw-r--r-- | libgo/runtime/go-rune.c | 35 |
1 files changed, 23 insertions, 12 deletions
diff --git a/libgo/runtime/go-rune.c b/libgo/runtime/go-rune.c index acdecb0..2caf800 100644 --- a/libgo/runtime/go-rune.c +++ b/libgo/runtime/go-rune.c @@ -15,7 +15,7 @@ int __go_get_rune (const unsigned char *str, size_t len, int *rune) { - int c, c1, c2, c3; + int c, c1, c2, c3, l; /* Default to the "replacement character". */ *rune = 0xfffd; @@ -37,8 +37,10 @@ __go_get_rune (const unsigned char *str, size_t len, int *rune) if ((c & 0xe0) == 0xc0 && (c1 & 0xc0) == 0x80) { - *rune = (((c & 0x1f) << 6) - + (c1 & 0x3f)); + l = (((c & 0x1f) << 6) + (c1 & 0x3f)); + if (l <= 0x7f) + return 1; + *rune = l; return 2; } @@ -50,17 +52,21 @@ __go_get_rune (const unsigned char *str, size_t len, int *rune) && (c1 & 0xc0) == 0x80 && (c2 & 0xc0) == 0x80) { - *rune = (((c & 0xf) << 12) - + ((c1 & 0x3f) << 6) - + (c2 & 0x3f)); + l = (((c & 0xf) << 12) + + ((c1 & 0x3f) << 6) + + (c2 & 0x3f)); - if (*rune >= 0xd800 && *rune < 0xe000) + if (l <= 0x7ff) + return 1; + + if (l >= 0xd800 && l < 0xe000) { /* Invalid surrogate half; return replace character. */ - *rune = 0xfffd; return 1; } + *rune = l; + return 3; } @@ -73,10 +79,15 @@ __go_get_rune (const unsigned char *str, size_t len, int *rune) && (c2 & 0xc0) == 0x80 && (c3 & 0xc0) == 0x80) { - *rune = (((c & 0x7) << 18) - + ((c1 & 0x3f) << 12) - + ((c2 & 0x3f) << 6) - + (c3 & 0x3f)); + l = (((c & 0x7) << 18) + + ((c1 & 0x3f) << 12) + + ((c2 & 0x3f) << 6) + + (c3 & 0x3f)); + + if (l <= 0xffff || l > 0x10ffff) + return 1; + + *rune = l; return 4; } |