The test requires perlio.
[p5sagit/p5-mst-13.2.git] / pp_pack.c
index ff2f8e0..b66d682 100644 (file)
--- a/pp_pack.c
+++ b/pp_pack.c
@@ -1,6 +1,6 @@
 /*    pp_pack.c
  *
- *    Copyright (c) 1991-2001, Larry Wall
+ *    Copyright (c) 1991-2002, Larry Wall
  *
  *    You may distribute under the terms of either the GNU General Public
  *    License or the Artistic License, as specified in the README file.
@@ -266,13 +266,14 @@ PP(pp_unpack)
                goto uchar_checksum;
            sv = NEWSV(35, len);
            sv_setpvn(sv, s, len);
-           s += len;
            if (datumtype == 'A' || datumtype == 'Z') {
                aptr = s;       /* borrow register */
                if (datumtype == 'Z') { /* 'Z' strips stuff after first null */
                    s = SvPVX(sv);
                    while (*s)
                        s++;
+                   if (star) /* exact for 'Z*' */
+                       len = s - SvPVX(sv) + 1;
                }
                else {          /* 'A' strips both nulls and spaces */
                    s = SvPVX(sv) + len - 1;
@@ -283,6 +284,7 @@ PP(pp_unpack)
                SvCUR_set(sv, s - SvPVX(sv));
                s = aptr;       /* unborrow register */
            }
+           s += len;
            XPUSHs(sv_2mortal(sv));
            break;
        case 'B':
@@ -447,7 +449,7 @@ PP(pp_unpack)
            if (checksum) {
                while (len-- > 0 && s < strend) {
                    STRLEN alen;
-                   auint = utf8n_to_uvchr((U8*)s, strend - s, &alen, 0);
+                   auint = NATIVE_TO_UNI(utf8n_to_uvchr((U8*)s, strend - s, &alen, 0));
                    along = alen;
                    s += along;
                    if (checksum > bits_in_uv)
@@ -461,7 +463,7 @@ PP(pp_unpack)
                EXTEND_MORTAL(len);
                while (len-- > 0 && s < strend) {
                    STRLEN alen;
-                   auint = utf8n_to_uvchr((U8*)s, strend - s, &alen, 0);
+                   auint = NATIVE_TO_UNI(utf8n_to_uvchr((U8*)s, strend - s, &alen, 0));
                    along = alen;
                    s += along;
                    sv = NEWSV(37, 0);
@@ -920,6 +922,8 @@ PP(pp_unpack)
            }
            break;
        case 'P':
+           if (star)
+               DIE(aTHX_ "P must have an explicit size");
            EXTEND(SP, 1);
            if (sizeof(char*) > strend - s)
                break;
@@ -1384,7 +1388,7 @@ PP(pp_pack)
        case 'a':
            fromstr = NEXTFROM;
            aptr = SvPV(fromstr, fromlen);
-           if (pat[-1] == '*') {
+           if (pat[lengthcode ? -2 : -1] == '*') { /* -2 after '/' */  
                len = fromlen;
                if (datumtype == 'Z')
                    ++len;
@@ -1554,7 +1558,7 @@ PP(pp_pack)
        case 'U':
            while (len-- > 0) {
                fromstr = NEXTFROM;
-               auint = SvUV(fromstr);
+               auint = UNI_TO_NATIVE(SvUV(fromstr));
                SvGROW(cat, SvCUR(cat) + UTF8_MAXLEN + 1);
                SvCUR_set(cat, (char*)uvchr_to_utf8((U8*)SvEND(cat),auint)
                               - SvPVX(cat));
@@ -1839,7 +1843,7 @@ PP(pp_pack)
            fromstr = NEXTFROM;
            aptr = SvPV(fromstr, fromlen);
            SvGROW(cat, fromlen * 4 / 3);
-           if (len <= 1)
+           if (len <= 2)
                len = 45;
            else
                len = len / 3 * 3;