summaryrefslogtreecommitdiff
path: root/pack.c
diff options
context:
space:
mode:
Diffstat (limited to 'pack.c')
-rw-r--r--pack.c22
1 files changed, 12 insertions, 10 deletions
diff --git a/pack.c b/pack.c
index b0b51c1b2a..86726518ce 100644
--- a/pack.c
+++ b/pack.c
@@ -889,8 +889,7 @@ pack_pack(ary, fmt)
t = 0;
}
else {
- StringValue(from);
- t = RSTRING(from)->ptr;
+ t = StringValuePtr(from);
}
if (!associates) {
associates = rb_ary_new();
@@ -1610,7 +1609,7 @@ pack_unpack(str, fmt)
{
VALUE buf = infected_str_new(0, (send - s)*3/4, str);
char *ptr = RSTRING(buf)->ptr;
- int a,b,c = 0,d;
+ int a = -1,b = -1,c = 0,d;
static int first = 1;
static int b64_xtable[256];
@@ -1625,7 +1624,7 @@ pack_unpack(str, fmt)
b64_xtable[(int)b64_table[i]] = i;
}
}
- for (;;) {
+ while (s < send) {
while (s[0] == '\r' || s[0] == '\n') { s++; }
if ((a = b64_xtable[(int)s[0]]) == -1) break;
if ((b = b64_xtable[(int)s[1]]) == -1) break;
@@ -1636,12 +1635,13 @@ pack_unpack(str, fmt)
*ptr++ = c << 6 | d;
s += 4;
}
- if (a != -1 && b != -1 && s[2] == '=') {
- *ptr++ = a << 2 | b >> 4;
- }
- if (a != -1 && b != -1 && c != -1 && s[3] == '=') {
- *ptr++ = a << 2 | b >> 4;
- *ptr++ = b << 4 | c >> 2;
+ if (a != -1 && b != -1) {
+ if (s + 2 < send && s[2] == '=')
+ *ptr++ = a << 2 | b >> 4;
+ if (c != -1 && s + 3 < send && s[3] == '=') {
+ *ptr++ = a << 2 | b >> 4;
+ *ptr++ = b << 4 | c >> 2;
+ }
}
*ptr = '\0';
RSTRING(buf)->len = ptr - RSTRING(buf)->ptr;
@@ -1677,6 +1677,8 @@ pack_unpack(str, fmt)
break;
case '@':
+ if (len > RSTRING(str)->len)
+ rb_raise(rb_eArgError, "@ outside of string");
s = RSTRING(str)->ptr + len;
break;