aboutsummaryrefslogtreecommitdiff
path: root/libgo/runtime/go-rune.c
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/runtime/go-rune.c')
-rw-r--r--libgo/runtime/go-rune.c35
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;
}