This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Change white space to avoid C++ deprecation warning
[perl5.git] / pp_pack.c
1 /*    pp_pack.c
2  *
3  *    Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
4  *    2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by Larry Wall and others
5  *
6  *    You may distribute under the terms of either the GNU General Public
7  *    License or the Artistic License, as specified in the README file.
8  *
9  */
10
11 /*
12  * He still hopefully carried some of his gear in his pack: a small tinder-box,
13  * two small shallow pans, the smaller fitting into the larger; inside them a
14  * wooden spoon, a short two-pronged fork and some skewers were stowed; and
15  * hidden at the bottom of the pack in a flat wooden box a dwindling treasure,
16  * some salt.
17  *
18  *     [p.653 of _The Lord of the Rings_, IV/iv: "Of Herbs and Stewed Rabbit"]
19  */
20
21 /* This file contains pp ("push/pop") functions that
22  * execute the opcodes that make up a perl program. A typical pp function
23  * expects to find its arguments on the stack, and usually pushes its
24  * results onto the stack, hence the 'pp' terminology. Each OP structure
25  * contains a pointer to the relevant pp_foo() function.
26  *
27  * This particular file just contains pp_pack() and pp_unpack(). See the
28  * other pp*.c files for the rest of the pp_ functions.
29  */
30
31 #include "EXTERN.h"
32 #define PERL_IN_PP_PACK_C
33 #include "perl.h"
34
35 /* Types used by pack/unpack */ 
36 typedef enum {
37   e_no_len,     /* no length  */
38   e_number,     /* number, [] */
39   e_star        /* asterisk   */
40 } howlen_t;
41
42 typedef struct tempsym {
43   const char*    patptr;   /* current template char */
44   const char*    patend;   /* one after last char   */
45   const char*    grpbeg;   /* 1st char of ()-group  */
46   const char*    grpend;   /* end of ()-group       */
47   I32      code;     /* template code (!<>)   */
48   I32      length;   /* length/repeat count   */
49   howlen_t howlen;   /* how length is given   */ 
50   int      level;    /* () nesting level      */
51   U32      flags;    /* /=4, comma=2, pack=1  */
52                      /*   and group modifiers */
53   STRLEN   strbeg;   /* offset of group start */
54   struct tempsym *previous; /* previous group */
55 } tempsym_t;
56
57 #define TEMPSYM_INIT(symptr, p, e, f) \
58     STMT_START {        \
59         (symptr)->patptr   = (p);       \
60         (symptr)->patend   = (e);       \
61         (symptr)->grpbeg   = NULL;      \
62         (symptr)->grpend   = NULL;      \
63         (symptr)->grpend   = NULL;      \
64         (symptr)->code     = 0;         \
65         (symptr)->length   = 0;         \
66         (symptr)->howlen   = e_no_len;  \
67         (symptr)->level    = 0;         \
68         (symptr)->flags    = (f);       \
69         (symptr)->strbeg   = 0;         \
70         (symptr)->previous = NULL;      \
71    } STMT_END
72
73 typedef union {
74     NV nv;
75     U8 bytes[sizeof(NV)];
76 } NV_bytes;
77
78 #if defined(HAS_LONG_DOUBLE) && defined(USE_LONG_DOUBLE)
79 typedef union {
80     long double ld;
81     U8 bytes[sizeof(long double)];
82 } ld_bytes;
83 #endif
84
85 #ifndef CHAR_BIT
86 # define CHAR_BIT       8
87 #endif
88 /* Maximum number of bytes to which a byte can grow due to upgrade */
89 #define UTF8_EXPAND     2
90
91 /*
92  * Offset for integer pack/unpack.
93  *
94  * On architectures where I16 and I32 aren't really 16 and 32 bits,
95  * which for now are all Crays, pack and unpack have to play games.
96  */
97
98 /*
99  * These values are required for portability of pack() output.
100  * If they're not right on your machine, then pack() and unpack()
101  * wouldn't work right anyway; you'll need to apply the Cray hack.
102  * (I'd like to check them with #if, but you can't use sizeof() in
103  * the preprocessor.)  --???
104  */
105 /*
106     The appropriate SHORTSIZE, INTSIZE, LONGSIZE, and LONGLONGSIZE
107     defines are now in config.h.  --Andy Dougherty  April 1998
108  */
109 #define SIZE16 2
110 #define SIZE32 4
111
112 /* CROSSCOMPILE and MULTIARCH are going to affect pp_pack() and pp_unpack().
113    --jhi Feb 1999 */
114
115 #if U16SIZE > SIZE16 || U32SIZE > SIZE32
116 #  if BYTEORDER == 0x1234 || BYTEORDER == 0x12345678    /* little-endian */
117 #    define OFF16(p)    ((char*)(p))
118 #    define OFF32(p)    ((char*)(p))
119 #  else
120 #    if BYTEORDER == 0x4321 || BYTEORDER == 0x87654321  /* big-endian */
121 #      define OFF16(p)  ((char*)(p) + (sizeof(U16) - SIZE16))
122 #      define OFF32(p)  ((char*)(p) + (sizeof(U32) - SIZE32))
123 #    else
124        ++++ bad cray byte order
125 #    endif
126 #  endif
127 #else
128 #  define OFF16(p)     ((char *) (p))
129 #  define OFF32(p)     ((char *) (p))
130 #endif
131
132 #define PUSH16(utf8, cur, p, needs_swap)                        \
133        PUSH_BYTES(utf8, cur, OFF16(p), SIZE16, needs_swap)
134 #define PUSH32(utf8, cur, p, needs_swap)                        \
135        PUSH_BYTES(utf8, cur, OFF32(p), SIZE32, needs_swap)
136
137 #if BYTEORDER == 0x4321 || BYTEORDER == 0x87654321  /* big-endian */
138 #  define NEEDS_SWAP(d)     (TYPE_ENDIANNESS(d) == TYPE_IS_LITTLE_ENDIAN)
139 #elif BYTEORDER == 0x1234 || BYTEORDER == 0x12345678  /* little-endian */
140 #  define NEEDS_SWAP(d)     (TYPE_ENDIANNESS(d) == TYPE_IS_BIG_ENDIAN)
141 #else
142 #  error "Unsupported byteorder"
143         /* Need to add code here to re-instate mixed endian support.
144            NEEDS_SWAP would need to hold a flag indicating which action to
145            take, and S_reverse_copy and the code in S_utf8_to_bytes would need
146            logic adding to deal with any mixed-endian transformations needed.
147         */
148 #endif
149
150 /* Only to be used inside a loop (see the break) */
151 #define SHIFT_BYTES(utf8, s, strend, buf, len, datumtype, needs_swap)   \
152 STMT_START {                                            \
153     if (UNLIKELY(utf8)) {                               \
154         if (!S_utf8_to_bytes(aTHX_ &s, strend,          \
155           (char *) (buf), len, datumtype)) break;       \
156     } else {                                            \
157         if (UNLIKELY(needs_swap))                       \
158             S_reverse_copy(s, (char *) (buf), len);     \
159         else                                            \
160             Copy(s, (char *) (buf), len, char);         \
161         s += len;                                       \
162     }                                                   \
163 } STMT_END
164
165 #define SHIFT16(utf8, s, strend, p, datumtype, needs_swap)              \
166        SHIFT_BYTES(utf8, s, strend, OFF16(p), SIZE16, datumtype, needs_swap)
167
168 #define SHIFT32(utf8, s, strend, p, datumtype, needs_swap)              \
169        SHIFT_BYTES(utf8, s, strend, OFF32(p), SIZE32, datumtype, needs_swap)
170
171 #define SHIFT_VAR(utf8, s, strend, var, datumtype, needs_swap)          \
172        SHIFT_BYTES(utf8, s, strend, &(var), sizeof(var), datumtype, needs_swap)
173
174 #define PUSH_VAR(utf8, aptr, var, needs_swap)           \
175        PUSH_BYTES(utf8, aptr, &(var), sizeof(var), needs_swap)
176
177 /* Avoid stack overflow due to pathological templates. 100 should be plenty. */
178 #define MAX_SUB_TEMPLATE_LEVEL 100
179
180 /* flags (note that type modifiers can also be used as flags!) */
181 #define FLAG_WAS_UTF8         0x40
182 #define FLAG_PARSE_UTF8       0x20      /* Parse as utf8 */
183 #define FLAG_UNPACK_ONLY_ONE  0x10
184 #define FLAG_DO_UTF8          0x08      /* The underlying string is utf8 */
185 #define FLAG_SLASH            0x04
186 #define FLAG_COMMA            0x02
187 #define FLAG_PACK             0x01
188
189 STATIC SV *
190 S_mul128(pTHX_ SV *sv, U8 m)
191 {
192   STRLEN          len;
193   char           *s = SvPV(sv, len);
194   char           *t;
195
196   PERL_ARGS_ASSERT_MUL128;
197
198   if (!strnEQ(s, "0000", 4)) {  /* need to grow sv */
199     SV * const tmpNew = newSVpvs("0000000000");
200
201     sv_catsv(tmpNew, sv);
202     SvREFCNT_dec(sv);           /* free old sv */
203     sv = tmpNew;
204     s = SvPV(sv, len);
205   }
206   t = s + len - 1;
207   while (!*t)                   /* trailing '\0'? */
208     t--;
209   while (t > s) {
210     const U32 i = ((*t - '0') << 7) + m;
211     *(t--) = '0' + (char)(i % 10);
212     m = (char)(i / 10);
213   }
214   return (sv);
215 }
216
217 /* Explosives and implosives. */
218
219 #define ISUUCHAR(ch)    (NATIVE_TO_LATIN1(ch) >= NATIVE_TO_LATIN1(' ')  \
220                       && NATIVE_TO_LATIN1(ch) <  NATIVE_TO_LATIN1('a'))
221
222 /* type modifiers */
223 #define TYPE_IS_SHRIEKING       0x100
224 #define TYPE_IS_BIG_ENDIAN      0x200
225 #define TYPE_IS_LITTLE_ENDIAN   0x400
226 #define TYPE_IS_PACK            0x800
227 #define TYPE_ENDIANNESS_MASK    (TYPE_IS_BIG_ENDIAN|TYPE_IS_LITTLE_ENDIAN)
228 #define TYPE_MODIFIERS(t)       ((t) & ~0xFF)
229 #define TYPE_NO_MODIFIERS(t)    ((t) & 0xFF)
230
231 # define TYPE_ENDIANNESS(t)     ((t) & TYPE_ENDIANNESS_MASK)
232 # define TYPE_NO_ENDIANNESS(t)  ((t) & ~TYPE_ENDIANNESS_MASK)
233
234 # define ENDIANNESS_ALLOWED_TYPES   "sSiIlLqQjJfFdDpP("
235
236 #define PACK_SIZE_CANNOT_CSUM           0x80
237 #define PACK_SIZE_UNPREDICTABLE         0x40    /* Not a fixed size element */
238 #define PACK_SIZE_MASK                  0x3F
239
240 #include "packsizetables.inc"
241
242 static void
243 S_reverse_copy(const char *src, char *dest, STRLEN len)
244 {
245     dest += len;
246     while (len--)
247         *--dest = *src++;
248 }
249
250 STATIC U8
251 utf8_to_byte(pTHX_ const char **s, const char *end, I32 datumtype)
252 {
253     STRLEN retlen;
254     UV val = utf8n_to_uvchr((U8 *) *s, end-*s, &retlen,
255                          ckWARN(WARN_UTF8) ? 0 : UTF8_ALLOW_ANY);
256     /* We try to process malformed UTF-8 as much as possible (preferably with
257        warnings), but these two mean we make no progress in the string and
258        might enter an infinite loop */
259     if (retlen == (STRLEN) -1 || retlen == 0)
260         Perl_croak(aTHX_ "Malformed UTF-8 string in '%c' format in unpack",
261                    (int) TYPE_NO_MODIFIERS(datumtype));
262     if (val >= 0x100) {
263         Perl_ck_warner(aTHX_ packWARN(WARN_UNPACK),
264                        "Character in '%c' format wrapped in unpack",
265                        (int) TYPE_NO_MODIFIERS(datumtype));
266         val &= 0xff;
267     }
268     *s += retlen;
269     return (U8)val;
270 }
271
272 #define SHIFT_BYTE(utf8, s, strend, datumtype) ((utf8) ? \
273         utf8_to_byte(aTHX_ &(s), (strend), (datumtype)) : \
274         *(U8 *)(s)++)
275
276 STATIC bool
277 S_utf8_to_bytes(pTHX_ const char **s, const char *end, const char *buf, int buf_len, I32 datumtype)
278 {
279     UV val;
280     STRLEN retlen;
281     const char *from = *s;
282     int bad = 0;
283     const U32 flags = ckWARN(WARN_UTF8) ?
284         UTF8_CHECK_ONLY : (UTF8_CHECK_ONLY | UTF8_ALLOW_ANY);
285     const bool needs_swap = NEEDS_SWAP(datumtype);
286
287     if (UNLIKELY(needs_swap))
288         buf += buf_len;
289
290     for (;buf_len > 0; buf_len--) {
291         if (from >= end) return FALSE;
292         val = utf8n_to_uvchr((U8 *) from, end-from, &retlen, flags);
293         if (retlen == (STRLEN) -1 || retlen == 0) {
294             from += UTF8SKIP(from);
295             bad |= 1;
296         } else from += retlen;
297         if (val >= 0x100) {
298             bad |= 2;
299             val &= 0xff;
300         }
301         if (UNLIKELY(needs_swap))
302             *(U8 *)--buf = (U8)val;
303         else
304             *(U8 *)buf++ = (U8)val;
305     }
306     /* We have enough characters for the buffer. Did we have problems ? */
307     if (bad) {
308         if (bad & 1) {
309             /* Rewalk the string fragment while warning */
310             const char *ptr;
311             const int flags = ckWARN(WARN_UTF8) ? 0 : UTF8_ALLOW_ANY;
312             for (ptr = *s; ptr < from; ptr += UTF8SKIP(ptr)) {
313                 if (ptr >= end) break;
314                 utf8n_to_uvchr((U8 *) ptr, end-ptr, &retlen, flags);
315             }
316             if (from > end) from = end;
317         }
318         if ((bad & 2))
319             Perl_ck_warner(aTHX_ packWARN(datumtype & TYPE_IS_PACK ?
320                                        WARN_PACK : WARN_UNPACK),
321                            "Character(s) in '%c' format wrapped in %s",
322                            (int) TYPE_NO_MODIFIERS(datumtype),
323                            datumtype & TYPE_IS_PACK ? "pack" : "unpack");
324     }
325     *s = from;
326     return TRUE;
327 }
328
329 STATIC char *
330 S_my_bytes_to_utf8(const U8 *start, STRLEN len, char *dest, const bool needs_swap) {
331     PERL_ARGS_ASSERT_MY_BYTES_TO_UTF8;
332
333     if (UNLIKELY(needs_swap)) {
334         const U8 *p = start + len;
335         while (p-- > start) {
336             append_utf8_from_native_byte(*p, (U8 **) & dest);
337         }
338     } else {
339         const U8 * const end = start + len;
340         while (start < end) {
341             append_utf8_from_native_byte(*start, (U8 **) & dest);
342             start++;
343         }
344     }
345     return dest;
346 }
347
348 #define PUSH_BYTES(utf8, cur, buf, len, needs_swap)             \
349 STMT_START {                                                    \
350     if (UNLIKELY(utf8))                                         \
351         (cur) = my_bytes_to_utf8((U8 *) buf, len, (cur), needs_swap);       \
352     else {                                                      \
353         if (UNLIKELY(needs_swap))                               \
354             S_reverse_copy((char *)(buf), cur, len);            \
355         else                                                    \
356             Copy(buf, cur, len, char);                          \
357         (cur) += (len);                                         \
358     }                                                           \
359 } STMT_END
360
361 #define GROWING(utf8, cat, start, cur, in_len)  \
362 STMT_START {                                    \
363     STRLEN glen = (in_len);                     \
364     if (utf8) glen *= UTF8_EXPAND;              \
365     if ((cur) + glen >= (start) + SvLEN(cat)) { \
366         (start) = sv_exp_grow(cat, glen);       \
367         (cur) = (start) + SvCUR(cat);           \
368     }                                           \
369 } STMT_END
370
371 #define PUSH_GROWING_BYTES(utf8, cat, start, cur, buf, in_len) \
372 STMT_START {                                    \
373     const STRLEN glen = (in_len);               \
374     STRLEN gl = glen;                           \
375     if (utf8) gl *= UTF8_EXPAND;                \
376     if ((cur) + gl >= (start) + SvLEN(cat)) {   \
377         *cur = '\0';                            \
378         SvCUR_set((cat), (cur) - (start));      \
379         (start) = sv_exp_grow(cat, gl);         \
380         (cur) = (start) + SvCUR(cat);           \
381     }                                           \
382     PUSH_BYTES(utf8, cur, buf, glen, 0);        \
383 } STMT_END
384
385 #define PUSH_BYTE(utf8, s, byte)                \
386 STMT_START {                                    \
387     if (utf8) {                                 \
388         const U8 au8 = (byte);                  \
389         (s) = my_bytes_to_utf8(&au8, 1, (s), 0);\
390     } else *(U8 *)(s)++ = (byte);               \
391 } STMT_END
392
393 /* Only to be used inside a loop (see the break) */
394 #define NEXT_UNI_VAL(val, cur, str, end, utf8_flags)            \
395 STMT_START {                                                    \
396     STRLEN retlen;                                              \
397     if (str >= end) break;                                      \
398     val = utf8n_to_uvchr((U8 *) str, end-str, &retlen, utf8_flags);     \
399     if (retlen == (STRLEN) -1 || retlen == 0) {                 \
400         *cur = '\0';                                            \
401         Perl_croak(aTHX_ "Malformed UTF-8 string in pack");     \
402     }                                                           \
403     str += retlen;                                              \
404 } STMT_END
405
406 static const char *_action( const tempsym_t* symptr )
407 {
408     return (const char *)(( symptr->flags & FLAG_PACK ) ? "pack" : "unpack");
409 }
410
411 /* Returns the sizeof() struct described by pat */
412 STATIC I32
413 S_measure_struct(pTHX_ tempsym_t* symptr)
414 {
415     I32 total = 0;
416
417     PERL_ARGS_ASSERT_MEASURE_STRUCT;
418
419     while (next_symbol(symptr)) {
420         I32 len;
421         int size;
422
423         switch (symptr->howlen) {
424           case e_star:
425             Perl_croak(aTHX_ "Within []-length '*' not allowed in %s",
426                         _action( symptr ) );
427
428           default:
429             /* e_no_len and e_number */
430             len = symptr->length;
431             break;
432         }
433
434         size = packprops[TYPE_NO_ENDIANNESS(symptr->code)] & PACK_SIZE_MASK;
435         if (!size) {
436             int star;
437             /* endianness doesn't influence the size of a type */
438             switch(TYPE_NO_ENDIANNESS(symptr->code)) {
439             default:
440                 Perl_croak(aTHX_ "Invalid type '%c' in %s",
441                            (int)TYPE_NO_MODIFIERS(symptr->code),
442                            _action( symptr ) );
443             case '.' | TYPE_IS_SHRIEKING:
444             case '@' | TYPE_IS_SHRIEKING:
445             case '@':
446             case '.':
447             case '/':
448             case 'U':                   /* XXXX Is it correct? */
449             case 'w':
450             case 'u':
451                 Perl_croak(aTHX_ "Within []-length '%c' not allowed in %s",
452                            (int) TYPE_NO_MODIFIERS(symptr->code),
453                            _action( symptr ) );
454             case '%':
455                 size = 0;
456                 break;
457             case '(':
458             {
459                 tempsym_t savsym = *symptr;
460                 symptr->patptr = savsym.grpbeg;
461                 symptr->patend = savsym.grpend;
462                 /* XXXX Theoretically, we need to measure many times at
463                    different positions, since the subexpression may contain
464                    alignment commands, but be not of aligned length.
465                    Need to detect this and croak().  */
466                 size = measure_struct(symptr);
467                 *symptr = savsym;
468                 break;
469             }
470             case 'X' | TYPE_IS_SHRIEKING:
471                 /* XXXX Is this useful?  Then need to treat MEASURE_BACKWARDS.
472                  */
473                 if (!len)               /* Avoid division by 0 */
474                     len = 1;
475                 len = total % len;      /* Assumed: the start is aligned. */
476                 /* FALLTHROUGH */
477             case 'X':
478                 size = -1;
479                 if (total < len)
480                     Perl_croak(aTHX_ "'X' outside of string in %s", _action( symptr ) );
481                 break;
482             case 'x' | TYPE_IS_SHRIEKING:
483                 if (!len)               /* Avoid division by 0 */
484                     len = 1;
485                 star = total % len;     /* Assumed: the start is aligned. */
486                 if (star)               /* Other portable ways? */
487                     len = len - star;
488                 else
489                     len = 0;
490                 /* FALLTHROUGH */
491             case 'x':
492             case 'A':
493             case 'Z':
494             case 'a':
495                 size = 1;
496                 break;
497             case 'B':
498             case 'b':
499                 len = (len + 7)/8;
500                 size = 1;
501                 break;
502             case 'H':
503             case 'h':
504                 len = (len + 1)/2;
505                 size = 1;
506                 break;
507
508             case 'P':
509                 len = 1;
510                 size = sizeof(char*);
511                 break;
512             }
513         }
514         total += len * size;
515     }
516     return total;
517 }
518
519
520 /* locate matching closing parenthesis or bracket
521  * returns char pointer to char after match, or NULL
522  */
523 STATIC const char *
524 S_group_end(pTHX_ const char *patptr, const char *patend, char ender)
525 {
526     PERL_ARGS_ASSERT_GROUP_END;
527
528     while (patptr < patend) {
529         const char c = *patptr++;
530
531         if (isSPACE(c))
532             continue;
533         else if (c == ender)
534             return patptr-1;
535         else if (c == '#') {
536             while (patptr < patend && *patptr != '\n')
537                 patptr++;
538             continue;
539         } else if (c == '(')
540             patptr = group_end(patptr, patend, ')') + 1;
541         else if (c == '[')
542             patptr = group_end(patptr, patend, ']') + 1;
543     }
544     Perl_croak(aTHX_ "No group ending character '%c' found in template",
545                ender);
546     NOT_REACHED; /* NOTREACHED */
547 }
548
549
550 /* Convert unsigned decimal number to binary.
551  * Expects a pointer to the first digit and address of length variable
552  * Advances char pointer to 1st non-digit char and returns number
553  */
554 STATIC const char *
555 S_get_num(pTHX_ const char *patptr, I32 *lenptr )
556 {
557   I32 len = *patptr++ - '0';
558
559   PERL_ARGS_ASSERT_GET_NUM;
560
561   while (isDIGIT(*patptr)) {
562     if (len >= 0x7FFFFFFF/10)
563       Perl_croak(aTHX_ "pack/unpack repeat count overflow");
564     len = (len * 10) + (*patptr++ - '0');
565   }
566   *lenptr = len;
567   return patptr;
568 }
569
570 /* The marvellous template parsing routine: Using state stored in *symptr,
571  * locates next template code and count
572  */
573 STATIC bool
574 S_next_symbol(pTHX_ tempsym_t* symptr )
575 {
576   const char* patptr = symptr->patptr;
577   const char* const patend = symptr->patend;
578
579   PERL_ARGS_ASSERT_NEXT_SYMBOL;
580
581   symptr->flags &= ~FLAG_SLASH;
582
583   while (patptr < patend) {
584     if (isSPACE(*patptr))
585       patptr++;
586     else if (*patptr == '#') {
587       patptr++;
588       while (patptr < patend && *patptr != '\n')
589         patptr++;
590       if (patptr < patend)
591         patptr++;
592     } else {
593       /* We should have found a template code */
594       I32 code = *patptr++ & 0xFF;
595       U32 inherited_modifiers = 0;
596
597       if (code == ','){ /* grandfather in commas but with a warning */
598         if (((symptr->flags & FLAG_COMMA) == 0) && ckWARN(WARN_UNPACK)){
599           symptr->flags |= FLAG_COMMA;
600           Perl_warner(aTHX_ packWARN(WARN_UNPACK),
601                       "Invalid type ',' in %s", _action( symptr ) );
602         }
603         continue;
604       }
605
606       /* for '(', skip to ')' */
607       if (code == '(') {
608         if( isDIGIT(*patptr) || *patptr == '*' || *patptr == '[' )
609           Perl_croak(aTHX_ "()-group starts with a count in %s",
610                         _action( symptr ) );
611         symptr->grpbeg = patptr;
612         patptr = 1 + ( symptr->grpend = group_end(patptr, patend, ')') );
613         if( symptr->level >= MAX_SUB_TEMPLATE_LEVEL )
614           Perl_croak(aTHX_ "Too deeply nested ()-groups in %s",
615                         _action( symptr ) );
616       }
617
618       /* look for group modifiers to inherit */
619       if (TYPE_ENDIANNESS(symptr->flags)) {
620         if (strchr(ENDIANNESS_ALLOWED_TYPES, TYPE_NO_MODIFIERS(code)))
621           inherited_modifiers |= TYPE_ENDIANNESS(symptr->flags);
622       }
623
624       /* look for modifiers */
625       while (patptr < patend) {
626         const char *allowed;
627         I32 modifier;
628         switch (*patptr) {
629           case '!':
630             modifier = TYPE_IS_SHRIEKING;
631             allowed = "sSiIlLxXnNvV@.";
632             break;
633           case '>':
634             modifier = TYPE_IS_BIG_ENDIAN;
635             allowed = ENDIANNESS_ALLOWED_TYPES;
636             break;
637           case '<':
638             modifier = TYPE_IS_LITTLE_ENDIAN;
639             allowed = ENDIANNESS_ALLOWED_TYPES;
640             break;
641           default:
642             allowed = "";
643             modifier = 0;
644             break;
645         }
646
647         if (modifier == 0)
648           break;
649
650         if (!strchr(allowed, TYPE_NO_MODIFIERS(code)))
651           Perl_croak(aTHX_ "'%c' allowed only after types %s in %s", *patptr,
652                         allowed, _action( symptr ) );
653
654         if (TYPE_ENDIANNESS(code | modifier) == TYPE_ENDIANNESS_MASK)
655           Perl_croak(aTHX_ "Can't use both '<' and '>' after type '%c' in %s",
656                      (int) TYPE_NO_MODIFIERS(code), _action( symptr ) );
657         else if (TYPE_ENDIANNESS(code | modifier | inherited_modifiers) ==
658                  TYPE_ENDIANNESS_MASK)
659           Perl_croak(aTHX_ "Can't use '%c' in a group with different byte-order in %s",
660                      *patptr, _action( symptr ) );
661
662         if ((code & modifier)) {
663             Perl_ck_warner(aTHX_ packWARN(WARN_UNPACK),
664                            "Duplicate modifier '%c' after '%c' in %s",
665                            *patptr, (int) TYPE_NO_MODIFIERS(code),
666                            _action( symptr ) );
667         }
668
669         code |= modifier;
670         patptr++;
671       }
672
673       /* inherit modifiers */
674       code |= inherited_modifiers;
675
676       /* look for count and/or / */
677       if (patptr < patend) {
678         if (isDIGIT(*patptr)) {
679           patptr = get_num( patptr, &symptr->length );
680           symptr->howlen = e_number;
681
682         } else if (*patptr == '*') {
683           patptr++;
684           symptr->howlen = e_star;
685
686         } else if (*patptr == '[') {
687           const char* lenptr = ++patptr;
688           symptr->howlen = e_number;
689           patptr = group_end( patptr, patend, ']' ) + 1;
690           /* what kind of [] is it? */
691           if (isDIGIT(*lenptr)) {
692             lenptr = get_num( lenptr, &symptr->length );
693             if( *lenptr != ']' )
694               Perl_croak(aTHX_ "Malformed integer in [] in %s",
695                             _action( symptr ) );
696           } else {
697             tempsym_t savsym = *symptr;
698             symptr->patend = patptr-1;
699             symptr->patptr = lenptr;
700             savsym.length = measure_struct(symptr);
701             *symptr = savsym;
702           }
703         } else {
704           symptr->howlen = e_no_len;
705           symptr->length = 1;
706         }
707
708         /* try to find / */
709         while (patptr < patend) {
710           if (isSPACE(*patptr))
711             patptr++;
712           else if (*patptr == '#') {
713             patptr++;
714             while (patptr < patend && *patptr != '\n')
715               patptr++;
716             if (patptr < patend)
717               patptr++;
718           } else {
719             if (*patptr == '/') {
720               symptr->flags |= FLAG_SLASH;
721               patptr++;
722               if (patptr < patend &&
723                   (isDIGIT(*patptr) || *patptr == '*' || *patptr == '['))
724                 Perl_croak(aTHX_ "'/' does not take a repeat count in %s",
725                             _action( symptr ) );
726             }
727             break;
728           }
729         }
730       } else {
731         /* at end - no count, no / */
732         symptr->howlen = e_no_len;
733         symptr->length = 1;
734       }
735
736       symptr->code = code;
737       symptr->patptr = patptr;
738       return TRUE;
739     }
740   }
741   symptr->patptr = patptr;
742   return FALSE;
743 }
744
745 /*
746    There is no way to cleanly handle the case where we should process the
747    string per byte in its upgraded form while it's really in downgraded form
748    (e.g. estimates like strend-s as an upper bound for the number of
749    characters left wouldn't work). So if we foresee the need of this
750    (pattern starts with U or contains U0), we want to work on the encoded
751    version of the string. Users are advised to upgrade their pack string
752    themselves if they need to do a lot of unpacks like this on it
753 */
754 STATIC bool
755 need_utf8(const char *pat, const char *patend)
756 {
757     bool first = TRUE;
758
759     PERL_ARGS_ASSERT_NEED_UTF8;
760
761     while (pat < patend) {
762         if (pat[0] == '#') {
763             pat++;
764             pat = (const char *) memchr(pat, '\n', patend-pat);
765             if (!pat) return FALSE;
766         } else if (pat[0] == 'U') {
767             if (first || pat[1] == '0') return TRUE;
768         } else first = FALSE;
769         pat++;
770     }
771     return FALSE;
772 }
773
774 STATIC char
775 first_symbol(const char *pat, const char *patend) {
776     PERL_ARGS_ASSERT_FIRST_SYMBOL;
777
778     while (pat < patend) {
779         if (pat[0] != '#') return pat[0];
780         pat++;
781         pat = (const char *) memchr(pat, '\n', patend-pat);
782         if (!pat) return 0;
783         pat++;
784     }
785     return 0;
786 }
787
788 /*
789
790 =head1 Pack and Unpack
791
792 =for apidoc unpackstring
793
794 The engine implementing the C<unpack()> Perl function.
795
796 Using the template C<pat..patend>, this function unpacks the string
797 C<s..strend> into a number of mortal SVs, which it pushes onto the perl
798 argument (C<@_>) stack (so you will need to issue a C<PUTBACK> before and
799 C<SPAGAIN> after the call to this function).  It returns the number of
800 pushed elements.
801
802 The C<strend> and C<patend> pointers should point to the byte following the
803 last character of each string.
804
805 Although this function returns its values on the perl argument stack, it
806 doesn't take any parameters from that stack (and thus in particular
807 there's no need to do a C<PUSHMARK> before calling it, unlike L</call_pv> for
808 example).
809
810 =cut */
811
812 I32
813 Perl_unpackstring(pTHX_ const char *pat, const char *patend, const char *s, const char *strend, U32 flags)
814 {
815     tempsym_t sym;
816
817     PERL_ARGS_ASSERT_UNPACKSTRING;
818
819     if (flags & FLAG_DO_UTF8) flags |= FLAG_WAS_UTF8;
820     else if (need_utf8(pat, patend)) {
821         /* We probably should try to avoid this in case a scalar context call
822            wouldn't get to the "U0" */
823         STRLEN len = strend - s;
824         s = (char *) bytes_to_utf8((U8 *) s, &len);
825         SAVEFREEPV(s);
826         strend = s + len;
827         flags |= FLAG_DO_UTF8;
828     }
829
830     if (first_symbol(pat, patend) != 'U' && (flags & FLAG_DO_UTF8))
831         flags |= FLAG_PARSE_UTF8;
832
833     TEMPSYM_INIT(&sym, pat, patend, flags);
834
835     return unpack_rec(&sym, s, s, strend, NULL );
836 }
837
838 STATIC I32
839 S_unpack_rec(pTHX_ tempsym_t* symptr, const char *s, const char *strbeg, const char *strend, const char **new_s )
840 {
841     dSP;
842     SV *sv = NULL;
843     const I32 start_sp_offset = SP - PL_stack_base;
844     howlen_t howlen;
845     I32 checksum = 0;
846     UV cuv = 0;
847     NV cdouble = 0.0;
848     const int bits_in_uv = CHAR_BIT * sizeof(cuv);
849     bool beyond = FALSE;
850     bool explicit_length;
851     const bool unpack_only_one = (symptr->flags & FLAG_UNPACK_ONLY_ONE) != 0;
852     bool utf8 = (symptr->flags & FLAG_PARSE_UTF8) ? 1 : 0;
853
854     PERL_ARGS_ASSERT_UNPACK_REC;
855
856     symptr->strbeg = s - strbeg;
857
858     while (next_symbol(symptr)) {
859         packprops_t props;
860         I32 len;
861         I32 datumtype = symptr->code;
862         bool needs_swap;
863         /* do first one only unless in list context
864            / is implemented by unpacking the count, then popping it from the
865            stack, so must check that we're not in the middle of a /  */
866         if ( unpack_only_one
867              && (SP - PL_stack_base == start_sp_offset + 1)
868              && (datumtype != '/') )   /* XXX can this be omitted */
869             break;
870
871         switch (howlen = symptr->howlen) {
872           case e_star:
873             len = strend - strbeg;      /* long enough */
874             break;
875           default:
876             /* e_no_len and e_number */
877             len = symptr->length;
878             break;
879         }
880
881         explicit_length = TRUE;
882       redo_switch:
883         beyond = s >= strend;
884
885         props = packprops[TYPE_NO_ENDIANNESS(datumtype)];
886         if (props) {
887             /* props nonzero means we can process this letter. */
888             const long size = props & PACK_SIZE_MASK;
889             const long howmany = (strend - s) / size;
890             if (len > howmany)
891                 len = howmany;
892
893             if (!checksum || (props & PACK_SIZE_CANNOT_CSUM)) {
894                 if (len && unpack_only_one) len = 1;
895                 EXTEND(SP, len);
896                 EXTEND_MORTAL(len);
897             }
898         }
899
900         needs_swap = NEEDS_SWAP(datumtype);
901
902         switch(TYPE_NO_ENDIANNESS(datumtype)) {
903         default:
904             Perl_croak(aTHX_ "Invalid type '%c' in unpack", (int)TYPE_NO_MODIFIERS(datumtype) );
905
906         case '%':
907             if (howlen == e_no_len)
908                 len = 16;               /* len is not specified */
909             checksum = len;
910             cuv = 0;
911             cdouble = 0;
912             continue;
913
914         case '(':
915         {
916             tempsym_t savsym = *symptr;
917             const U32 group_modifiers = TYPE_MODIFIERS(datumtype & ~symptr->flags);
918             symptr->flags |= group_modifiers;
919             symptr->patend = savsym.grpend;
920             symptr->previous = &savsym;
921             symptr->level++;
922             PUTBACK;
923             if (len && unpack_only_one) len = 1;
924             while (len--) {
925                 symptr->patptr = savsym.grpbeg;
926                 if (utf8) symptr->flags |=  FLAG_PARSE_UTF8;
927                 else      symptr->flags &= ~FLAG_PARSE_UTF8;
928                 unpack_rec(symptr, s, strbeg, strend, &s);
929                 if (s == strend && savsym.howlen == e_star)
930                     break; /* No way to continue */
931             }
932             SPAGAIN;
933             savsym.flags = symptr->flags & ~group_modifiers;
934             *symptr = savsym;
935             break;
936         }
937         case '.' | TYPE_IS_SHRIEKING:
938         case '.': {
939             const char *from;
940             SV *sv;
941             const bool u8 = utf8 && !(datumtype & TYPE_IS_SHRIEKING);
942             if (howlen == e_star) from = strbeg;
943             else if (len <= 0) from = s;
944             else {
945                 tempsym_t *group = symptr;
946
947                 while (--len && group) group = group->previous;
948                 from = group ? strbeg + group->strbeg : strbeg;
949             }
950             sv = from <= s ?
951                 newSVuv(  u8 ? (UV) utf8_length((const U8*)from, (const U8*)s) : (UV) (s-from)) :
952                 newSViv(-(u8 ? (IV) utf8_length((const U8*)s, (const U8*)from) : (IV) (from-s)));
953             mXPUSHs(sv);
954             break;
955         }
956         case '@' | TYPE_IS_SHRIEKING:
957         case '@':
958             s = strbeg + symptr->strbeg;
959             if (utf8  && !(datumtype & TYPE_IS_SHRIEKING))
960             {
961                 while (len > 0) {
962                     if (s >= strend)
963                         Perl_croak(aTHX_ "'@' outside of string in unpack");
964                     s += UTF8SKIP(s);
965                     len--;
966                 }
967                 if (s > strend)
968                     Perl_croak(aTHX_ "'@' outside of string with malformed UTF-8 in unpack");
969             } else {
970                 if (strend-s < len)
971                     Perl_croak(aTHX_ "'@' outside of string in unpack");
972                 s += len;
973             }
974             break;
975         case 'X' | TYPE_IS_SHRIEKING:
976             if (!len)                   /* Avoid division by 0 */
977                 len = 1;
978             if (utf8) {
979                 const char *hop, *last;
980                 I32 l = len;
981                 hop = last = strbeg;
982                 while (hop < s) {
983                     hop += UTF8SKIP(hop);
984                     if (--l == 0) {
985                         last = hop;
986                         l = len;
987                     }
988                 }
989                 if (last > s)
990                     Perl_croak(aTHX_ "Malformed UTF-8 string in unpack");
991                 s = last;
992                 break;
993             }
994             len = (s - strbeg) % len;
995             /* FALLTHROUGH */
996         case 'X':
997             if (utf8) {
998                 while (len > 0) {
999                     if (s <= strbeg)
1000                         Perl_croak(aTHX_ "'X' outside of string in unpack");
1001                     while (--s, UTF8_IS_CONTINUATION(*s)) {
1002                         if (s <= strbeg)
1003                             Perl_croak(aTHX_ "'X' outside of string in unpack");
1004                     }
1005                     len--;
1006                 }
1007             } else {
1008                 if (len > s - strbeg)
1009                     Perl_croak(aTHX_ "'X' outside of string in unpack" );
1010                 s -= len;
1011             }
1012             break;
1013         case 'x' | TYPE_IS_SHRIEKING: {
1014             I32 ai32;
1015             if (!len)                   /* Avoid division by 0 */
1016                 len = 1;
1017             if (utf8) ai32 = utf8_length((U8 *) strbeg, (U8 *) s) % len;
1018             else      ai32 = (s - strbeg)                         % len;
1019             if (ai32 == 0) break;
1020             len -= ai32;
1021             }
1022             /* FALLTHROUGH */
1023         case 'x':
1024             if (utf8) {
1025                 while (len>0) {
1026                     if (s >= strend)
1027                         Perl_croak(aTHX_ "'x' outside of string in unpack");
1028                     s += UTF8SKIP(s);
1029                     len--;
1030                 }
1031             } else {
1032                 if (len > strend - s)
1033                     Perl_croak(aTHX_ "'x' outside of string in unpack");
1034                 s += len;
1035             }
1036             break;
1037         case '/':
1038             Perl_croak(aTHX_ "'/' must follow a numeric type in unpack");
1039
1040         case 'A':
1041         case 'Z':
1042         case 'a':
1043             if (checksum) {
1044                 /* Preliminary length estimate is assumed done in 'W' */
1045                 if (len > strend - s) len = strend - s;
1046                 goto W_checksum;
1047             }
1048             if (utf8) {
1049                 I32 l;
1050                 const char *hop;
1051                 for (l=len, hop=s; l>0; l--, hop += UTF8SKIP(hop)) {
1052                     if (hop >= strend) {
1053                         if (hop > strend)
1054                             Perl_croak(aTHX_ "Malformed UTF-8 string in unpack");
1055                         break;
1056                     }
1057                 }
1058                 if (hop > strend)
1059                     Perl_croak(aTHX_ "Malformed UTF-8 string in unpack");
1060                 len = hop - s;
1061             } else if (len > strend - s)
1062                 len = strend - s;
1063
1064             if (datumtype == 'Z') {
1065                 /* 'Z' strips stuff after first null */
1066                 const char *ptr, *end;
1067                 end = s + len;
1068                 for (ptr = s; ptr < end; ptr++) if (*ptr == 0) break;
1069                 sv = newSVpvn(s, ptr-s);
1070                 if (howlen == e_star) /* exact for 'Z*' */
1071                     len = ptr-s + (ptr != strend ? 1 : 0);
1072             } else if (datumtype == 'A') {
1073                 /* 'A' strips both nulls and spaces */
1074                 const char *ptr;
1075                 if (utf8 && (symptr->flags & FLAG_WAS_UTF8)) {
1076                     for (ptr = s+len-1; ptr >= s; ptr--)
1077                         if (*ptr != 0 && !UTF8_IS_CONTINUATION(*ptr) &&
1078                             !isSPACE_utf8(ptr)) break;
1079                     if (ptr >= s) ptr += UTF8SKIP(ptr);
1080                     else ptr++;
1081                     if (ptr > s+len)
1082                         Perl_croak(aTHX_ "Malformed UTF-8 string in unpack");
1083                 } else {
1084                     for (ptr = s+len-1; ptr >= s; ptr--)
1085                         if (*ptr != 0 && !isSPACE(*ptr)) break;
1086                     ptr++;
1087                 }
1088                 sv = newSVpvn(s, ptr-s);
1089             } else sv = newSVpvn(s, len);
1090
1091             if (utf8) {
1092                 SvUTF8_on(sv);
1093                 /* Undo any upgrade done due to need_utf8() */
1094                 if (!(symptr->flags & FLAG_WAS_UTF8))
1095                     sv_utf8_downgrade(sv, 0);
1096             }
1097             mXPUSHs(sv);
1098             s += len;
1099             break;
1100         case 'B':
1101         case 'b': {
1102             char *str;
1103             if (howlen == e_star || len > (strend - s) * 8)
1104                 len = (strend - s) * 8;
1105             if (checksum) {
1106                 if (utf8)
1107                     while (len >= 8 && s < strend) {
1108                         cuv += PL_bitcount[utf8_to_byte(aTHX_ &s, strend, datumtype)];
1109                         len -= 8;
1110                     }
1111                 else
1112                     while (len >= 8) {
1113                         cuv += PL_bitcount[*(U8 *)s++];
1114                         len -= 8;
1115                     }
1116                 if (len && s < strend) {
1117                     U8 bits;
1118                     bits = SHIFT_BYTE(utf8, s, strend, datumtype);
1119                     if (datumtype == 'b')
1120                         while (len-- > 0) {
1121                             if (bits & 1) cuv++;
1122                             bits >>= 1;
1123                         }
1124                     else
1125                         while (len-- > 0) {
1126                             if (bits & 0x80) cuv++;
1127                             bits <<= 1;
1128                         }
1129                 }
1130                 break;
1131             }
1132
1133             sv = sv_2mortal(newSV(len ? len : 1));
1134             SvPOK_on(sv);
1135             str = SvPVX(sv);
1136             if (datumtype == 'b') {
1137                 U8 bits = 0;
1138                 const I32 ai32 = len;
1139                 for (len = 0; len < ai32; len++) {
1140                     if (len & 7) bits >>= 1;
1141                     else if (utf8) {
1142                         if (s >= strend) break;
1143                         bits = utf8_to_byte(aTHX_ &s, strend, datumtype);
1144                     } else bits = *(U8 *) s++;
1145                     *str++ = bits & 1 ? '1' : '0';
1146                 }
1147             } else {
1148                 U8 bits = 0;
1149                 const I32 ai32 = len;
1150                 for (len = 0; len < ai32; len++) {
1151                     if (len & 7) bits <<= 1;
1152                     else if (utf8) {
1153                         if (s >= strend) break;
1154                         bits = utf8_to_byte(aTHX_ &s, strend, datumtype);
1155                     } else bits = *(U8 *) s++;
1156                     *str++ = bits & 0x80 ? '1' : '0';
1157                 }
1158             }
1159             *str = '\0';
1160             SvCUR_set(sv, str - SvPVX_const(sv));
1161             XPUSHs(sv);
1162             break;
1163         }
1164         case 'H':
1165         case 'h': {
1166             char *str = NULL;
1167             /* Preliminary length estimate, acceptable for utf8 too */
1168             if (howlen == e_star || len > (strend - s) * 2)
1169                 len = (strend - s) * 2;
1170             if (!checksum) {
1171                 sv = sv_2mortal(newSV(len ? len : 1));
1172                 SvPOK_on(sv);
1173                 str = SvPVX(sv);
1174             }
1175             if (datumtype == 'h') {
1176                 U8 bits = 0;
1177                 I32 ai32 = len;
1178                 for (len = 0; len < ai32; len++) {
1179                     if (len & 1) bits >>= 4;
1180                     else if (utf8) {
1181                         if (s >= strend) break;
1182                         bits = utf8_to_byte(aTHX_ &s, strend, datumtype);
1183                     } else bits = * (U8 *) s++;
1184                     if (!checksum)
1185                         *str++ = PL_hexdigit[bits & 15];
1186                 }
1187             } else {
1188                 U8 bits = 0;
1189                 const I32 ai32 = len;
1190                 for (len = 0; len < ai32; len++) {
1191                     if (len & 1) bits <<= 4;
1192                     else if (utf8) {
1193                         if (s >= strend) break;
1194                         bits = utf8_to_byte(aTHX_ &s, strend, datumtype);
1195                     } else bits = *(U8 *) s++;
1196                     if (!checksum)
1197                         *str++ = PL_hexdigit[(bits >> 4) & 15];
1198                 }
1199             }
1200             if (!checksum) {
1201                 *str = '\0';
1202                 SvCUR_set(sv, str - SvPVX_const(sv));
1203                 XPUSHs(sv);
1204             }
1205             break;
1206         }
1207         case 'C':
1208             if (len == 0) {
1209                 if (explicit_length)
1210                     /* Switch to "character" mode */
1211                     utf8 = (symptr->flags & FLAG_DO_UTF8) ? 1 : 0;
1212                 break;
1213             }
1214             /* FALLTHROUGH */
1215         case 'c':
1216             while (len-- > 0 && s < strend) {
1217                 int aint;
1218                 if (utf8)
1219                   {
1220                     STRLEN retlen;
1221                     aint = utf8n_to_uvchr((U8 *) s, strend-s, &retlen,
1222                                  ckWARN(WARN_UTF8) ? 0 : UTF8_ALLOW_ANY);
1223                     if (retlen == (STRLEN) -1 || retlen == 0)
1224                         Perl_croak(aTHX_ "Malformed UTF-8 string in unpack");
1225                     s += retlen;
1226                   }
1227                 else
1228                   aint = *(U8 *)(s)++;
1229                 if (aint >= 128 && datumtype != 'C')    /* fake up signed chars */
1230                     aint -= 256;
1231                 if (!checksum)
1232                     mPUSHi(aint);
1233                 else if (checksum > bits_in_uv)
1234                     cdouble += (NV)aint;
1235                 else
1236                     cuv += aint;
1237             }
1238             break;
1239         case 'W':
1240           W_checksum:
1241             if (utf8) {
1242                 while (len-- > 0 && s < strend) {
1243                     STRLEN retlen;
1244                     const UV val = utf8n_to_uvchr((U8 *) s, strend-s, &retlen,
1245                                          ckWARN(WARN_UTF8) ? 0 : UTF8_ALLOW_ANY);
1246                     if (retlen == (STRLEN) -1 || retlen == 0)
1247                         Perl_croak(aTHX_ "Malformed UTF-8 string in unpack");
1248                     s += retlen;
1249                     if (!checksum)
1250                         mPUSHu(val);
1251                     else if (checksum > bits_in_uv)
1252                         cdouble += (NV) val;
1253                     else
1254                         cuv += val;
1255                 }
1256             } else if (!checksum)
1257                 while (len-- > 0) {
1258                     const U8 ch = *(U8 *) s++;
1259                     mPUSHu(ch);
1260             }
1261             else if (checksum > bits_in_uv)
1262                 while (len-- > 0) cdouble += (NV) *(U8 *) s++;
1263             else
1264                 while (len-- > 0) cuv += *(U8 *) s++;
1265             break;
1266         case 'U':
1267             if (len == 0) {
1268                 if (explicit_length && howlen != e_star) {
1269                     /* Switch to "bytes in UTF-8" mode */
1270                     if (symptr->flags & FLAG_DO_UTF8) utf8 = 0;
1271                     else
1272                         /* Should be impossible due to the need_utf8() test */
1273                         Perl_croak(aTHX_ "U0 mode on a byte string");
1274                 }
1275                 break;
1276             }
1277             if (len > strend - s) len = strend - s;
1278             if (!checksum) {
1279                 if (len && unpack_only_one) len = 1;
1280                 EXTEND(SP, len);
1281                 EXTEND_MORTAL(len);
1282             }
1283             while (len-- > 0 && s < strend) {
1284                 STRLEN retlen;
1285                 UV auv;
1286                 if (utf8) {
1287                     U8 result[UTF8_MAXLEN];
1288                     const char *ptr = s;
1289                     STRLEN len;
1290                     /* Bug: warns about bad utf8 even if we are short on bytes
1291                        and will break out of the loop */
1292                     if (!S_utf8_to_bytes(aTHX_ &ptr, strend, (char *) result, 1,
1293                                       'U'))
1294                         break;
1295                     len = UTF8SKIP(result);
1296                     if (!S_utf8_to_bytes(aTHX_ &ptr, strend,
1297                                       (char *) &result[1], len-1, 'U')) break;
1298                     auv = NATIVE_TO_UNI(utf8n_to_uvchr(result,
1299                                                        len,
1300                                                        &retlen,
1301                                                        UTF8_ALLOW_DEFAULT));
1302                     s = ptr;
1303                 } else {
1304                     auv = NATIVE_TO_UNI(utf8n_to_uvchr((U8*)s,
1305                                                        strend - s,
1306                                                        &retlen,
1307                                                        UTF8_ALLOW_DEFAULT));
1308                     if (retlen == (STRLEN) -1 || retlen == 0)
1309                         Perl_croak(aTHX_ "Malformed UTF-8 string in unpack");
1310                     s += retlen;
1311                 }
1312                 if (!checksum)
1313                     mPUSHu(auv);
1314                 else if (checksum > bits_in_uv)
1315                     cdouble += (NV) auv;
1316                 else
1317                     cuv += auv;
1318             }
1319             break;
1320         case 's' | TYPE_IS_SHRIEKING:
1321 #if SHORTSIZE != SIZE16
1322             while (len-- > 0) {
1323                 short ashort;
1324                 SHIFT_VAR(utf8, s, strend, ashort, datumtype, needs_swap);
1325                 if (!checksum)
1326                     mPUSHi(ashort);
1327                 else if (checksum > bits_in_uv)
1328                     cdouble += (NV)ashort;
1329                 else
1330                     cuv += ashort;
1331             }
1332             break;
1333 #else
1334             /* FALLTHROUGH */
1335 #endif
1336         case 's':
1337             while (len-- > 0) {
1338                 I16 ai16;
1339
1340 #if U16SIZE > SIZE16
1341                 ai16 = 0;
1342 #endif
1343                 SHIFT16(utf8, s, strend, &ai16, datumtype, needs_swap);
1344 #if U16SIZE > SIZE16
1345                 if (ai16 > 32767)
1346                     ai16 -= 65536;
1347 #endif
1348                 if (!checksum)
1349                     mPUSHi(ai16);
1350                 else if (checksum > bits_in_uv)
1351                     cdouble += (NV)ai16;
1352                 else
1353                     cuv += ai16;
1354             }
1355             break;
1356         case 'S' | TYPE_IS_SHRIEKING:
1357 #if SHORTSIZE != SIZE16
1358             while (len-- > 0) {
1359                 unsigned short aushort;
1360                 SHIFT_VAR(utf8, s, strend, aushort, datumtype, needs_swap,
1361                           needs_swap);
1362                 if (!checksum)
1363                     mPUSHu(aushort);
1364                 else if (checksum > bits_in_uv)
1365                     cdouble += (NV)aushort;
1366                 else
1367                     cuv += aushort;
1368             }
1369             break;
1370 #else
1371             /* FALLTHROUGH */
1372 #endif
1373         case 'v':
1374         case 'n':
1375         case 'S':
1376             while (len-- > 0) {
1377                 U16 au16;
1378 #if U16SIZE > SIZE16
1379                 au16 = 0;
1380 #endif
1381                 SHIFT16(utf8, s, strend, &au16, datumtype, needs_swap);
1382                 if (datumtype == 'n')
1383                     au16 = PerlSock_ntohs(au16);
1384                 if (datumtype == 'v')
1385                     au16 = vtohs(au16);
1386                 if (!checksum)
1387                     mPUSHu(au16);
1388                 else if (checksum > bits_in_uv)
1389                     cdouble += (NV) au16;
1390                 else
1391                     cuv += au16;
1392             }
1393             break;
1394         case 'v' | TYPE_IS_SHRIEKING:
1395         case 'n' | TYPE_IS_SHRIEKING:
1396             while (len-- > 0) {
1397                 I16 ai16;
1398 # if U16SIZE > SIZE16
1399                 ai16 = 0;
1400 # endif
1401                 SHIFT16(utf8, s, strend, &ai16, datumtype, needs_swap);
1402                 /* There should never be any byte-swapping here.  */
1403                 assert(!TYPE_ENDIANNESS(datumtype));
1404                 if (datumtype == ('n' | TYPE_IS_SHRIEKING))
1405                     ai16 = (I16) PerlSock_ntohs((U16) ai16);
1406                 if (datumtype == ('v' | TYPE_IS_SHRIEKING))
1407                     ai16 = (I16) vtohs((U16) ai16);
1408                 if (!checksum)
1409                     mPUSHi(ai16);
1410                 else if (checksum > bits_in_uv)
1411                     cdouble += (NV) ai16;
1412                 else
1413                     cuv += ai16;
1414             }
1415             break;
1416         case 'i':
1417         case 'i' | TYPE_IS_SHRIEKING:
1418             while (len-- > 0) {
1419                 int aint;
1420                 SHIFT_VAR(utf8, s, strend, aint, datumtype, needs_swap);
1421                 if (!checksum)
1422                     mPUSHi(aint);
1423                 else if (checksum > bits_in_uv)
1424                     cdouble += (NV)aint;
1425                 else
1426                     cuv += aint;
1427             }
1428             break;
1429         case 'I':
1430         case 'I' | TYPE_IS_SHRIEKING:
1431             while (len-- > 0) {
1432                 unsigned int auint;
1433                 SHIFT_VAR(utf8, s, strend, auint, datumtype, needs_swap);
1434                 if (!checksum)
1435                     mPUSHu(auint);
1436                 else if (checksum > bits_in_uv)
1437                     cdouble += (NV)auint;
1438                 else
1439                     cuv += auint;
1440             }
1441             break;
1442         case 'j':
1443             while (len-- > 0) {
1444                 IV aiv;
1445                 SHIFT_VAR(utf8, s, strend, aiv, datumtype, needs_swap);
1446                 if (!checksum)
1447                     mPUSHi(aiv);
1448                 else if (checksum > bits_in_uv)
1449                     cdouble += (NV)aiv;
1450                 else
1451                     cuv += aiv;
1452             }
1453             break;
1454         case 'J':
1455             while (len-- > 0) {
1456                 UV auv;
1457                 SHIFT_VAR(utf8, s, strend, auv, datumtype, needs_swap);
1458                 if (!checksum)
1459                     mPUSHu(auv);
1460                 else if (checksum > bits_in_uv)
1461                     cdouble += (NV)auv;
1462                 else
1463                     cuv += auv;
1464             }
1465             break;
1466         case 'l' | TYPE_IS_SHRIEKING:
1467 #if LONGSIZE != SIZE32
1468             while (len-- > 0) {
1469                 long along;
1470                 SHIFT_VAR(utf8, s, strend, along, datumtype, needs_swap);
1471                 if (!checksum)
1472                     mPUSHi(along);
1473                 else if (checksum > bits_in_uv)
1474                     cdouble += (NV)along;
1475                 else
1476                     cuv += along;
1477             }
1478             break;
1479 #else
1480             /* FALLTHROUGH */
1481 #endif
1482         case 'l':
1483             while (len-- > 0) {
1484                 I32 ai32;
1485 #if U32SIZE > SIZE32
1486                 ai32 = 0;
1487 #endif
1488                 SHIFT32(utf8, s, strend, &ai32, datumtype, needs_swap);
1489 #if U32SIZE > SIZE32
1490                 if (ai32 > 2147483647) ai32 -= 4294967296;
1491 #endif
1492                 if (!checksum)
1493                     mPUSHi(ai32);
1494                 else if (checksum > bits_in_uv)
1495                     cdouble += (NV)ai32;
1496                 else
1497                     cuv += ai32;
1498             }
1499             break;
1500         case 'L' | TYPE_IS_SHRIEKING:
1501 #if LONGSIZE != SIZE32
1502             while (len-- > 0) {
1503                 unsigned long aulong;
1504                 SHIFT_VAR(utf8, s, strend, aulong, datumtype, needs_swap);
1505                 if (!checksum)
1506                     mPUSHu(aulong);
1507                 else if (checksum > bits_in_uv)
1508                     cdouble += (NV)aulong;
1509                 else
1510                     cuv += aulong;
1511             }
1512             break;
1513 #else
1514             /* FALLTHROUGH */
1515 #endif
1516         case 'V':
1517         case 'N':
1518         case 'L':
1519             while (len-- > 0) {
1520                 U32 au32;
1521 #if U32SIZE > SIZE32
1522                 au32 = 0;
1523 #endif
1524                 SHIFT32(utf8, s, strend, &au32, datumtype, needs_swap);
1525                 if (datumtype == 'N')
1526                     au32 = PerlSock_ntohl(au32);
1527                 if (datumtype == 'V')
1528                     au32 = vtohl(au32);
1529                 if (!checksum)
1530                     mPUSHu(au32);
1531                 else if (checksum > bits_in_uv)
1532                     cdouble += (NV)au32;
1533                 else
1534                     cuv += au32;
1535             }
1536             break;
1537         case 'V' | TYPE_IS_SHRIEKING:
1538         case 'N' | TYPE_IS_SHRIEKING:
1539             while (len-- > 0) {
1540                 I32 ai32;
1541 #if U32SIZE > SIZE32
1542                 ai32 = 0;
1543 #endif
1544                 SHIFT32(utf8, s, strend, &ai32, datumtype, needs_swap);
1545                 /* There should never be any byte swapping here.  */
1546                 assert(!TYPE_ENDIANNESS(datumtype));
1547                 if (datumtype == ('N' | TYPE_IS_SHRIEKING))
1548                     ai32 = (I32)PerlSock_ntohl((U32)ai32);
1549                 if (datumtype == ('V' | TYPE_IS_SHRIEKING))
1550                     ai32 = (I32)vtohl((U32)ai32);
1551                 if (!checksum)
1552                     mPUSHi(ai32);
1553                 else if (checksum > bits_in_uv)
1554                     cdouble += (NV)ai32;
1555                 else
1556                     cuv += ai32;
1557             }
1558             break;
1559         case 'p':
1560             while (len-- > 0) {
1561                 const char *aptr;
1562                 SHIFT_VAR(utf8, s, strend, aptr, datumtype, needs_swap);
1563                 /* newSVpv generates undef if aptr is NULL */
1564                 mPUSHs(newSVpv(aptr, 0));
1565             }
1566             break;
1567         case 'w':
1568             {
1569                 UV auv = 0;
1570                 U32 bytes = 0;
1571
1572                 while (len > 0 && s < strend) {
1573                     U8 ch;
1574                     ch = SHIFT_BYTE(utf8, s, strend, datumtype);
1575                     auv = (auv << 7) | (ch & 0x7f);
1576                     /* UTF8_IS_XXXXX not right here because this is a BER, not
1577                      * UTF-8 format - using constant 0x80 */
1578                     if (ch < 0x80) {
1579                         bytes = 0;
1580                         mPUSHu(auv);
1581                         len--;
1582                         auv = 0;
1583                         continue;
1584                     }
1585                     if (++bytes >= sizeof(UV)) {        /* promote to string */
1586                         const char *t;
1587
1588                         sv = Perl_newSVpvf(aTHX_ "%.*" UVuf,
1589                                                  (int)TYPE_DIGITS(UV), auv);
1590                         while (s < strend) {
1591                             ch = SHIFT_BYTE(utf8, s, strend, datumtype);
1592                             sv = mul128(sv, (U8)(ch & 0x7f));
1593                             if (!(ch & 0x80)) {
1594                                 bytes = 0;
1595                                 break;
1596                             }
1597                         }
1598                         t = SvPV_nolen_const(sv);
1599                         while (*t == '0')
1600                             t++;
1601                         sv_chop(sv, t);
1602                         mPUSHs(sv);
1603                         len--;
1604                         auv = 0;
1605                     }
1606                 }
1607                 if ((s >= strend) && bytes)
1608                     Perl_croak(aTHX_ "Unterminated compressed integer in unpack");
1609             }
1610             break;
1611         case 'P':
1612             if (symptr->howlen == e_star)
1613                 Perl_croak(aTHX_ "'P' must have an explicit size in unpack");
1614             EXTEND(SP, 1);
1615             if (s + sizeof(char*) <= strend) {
1616                 char *aptr;
1617                 SHIFT_VAR(utf8, s, strend, aptr, datumtype, needs_swap);
1618                 /* newSVpvn generates undef if aptr is NULL */
1619                 PUSHs(newSVpvn_flags(aptr, len, SVs_TEMP));
1620             }
1621             break;
1622 #if defined(HAS_QUAD) && IVSIZE >= 8
1623         case 'q':
1624             while (len-- > 0) {
1625                 Quad_t aquad;
1626                 SHIFT_VAR(utf8, s, strend, aquad, datumtype, needs_swap);
1627                 if (!checksum)
1628                     mPUSHs(newSViv((IV)aquad));
1629                 else if (checksum > bits_in_uv)
1630                     cdouble += (NV)aquad;
1631                 else
1632                     cuv += aquad;
1633             }
1634             break;
1635         case 'Q':
1636             while (len-- > 0) {
1637                 Uquad_t auquad;
1638                 SHIFT_VAR(utf8, s, strend, auquad, datumtype, needs_swap);
1639                 if (!checksum)
1640                     mPUSHs(newSVuv((UV)auquad));
1641                 else if (checksum > bits_in_uv)
1642                     cdouble += (NV)auquad;
1643                 else
1644                     cuv += auquad;
1645             }
1646             break;
1647 #endif
1648         /* float and double added gnb@melba.bby.oz.au 22/11/89 */
1649         case 'f':
1650             while (len-- > 0) {
1651                 float afloat;
1652                 SHIFT_VAR(utf8, s, strend, afloat, datumtype, needs_swap);
1653                 if (!checksum)
1654                     mPUSHn(afloat);
1655                 else
1656                     cdouble += afloat;
1657             }
1658             break;
1659         case 'd':
1660             while (len-- > 0) {
1661                 double adouble;
1662                 SHIFT_VAR(utf8, s, strend, adouble, datumtype, needs_swap);
1663                 if (!checksum)
1664                     mPUSHn(adouble);
1665                 else
1666                     cdouble += adouble;
1667             }
1668             break;
1669         case 'F':
1670             while (len-- > 0) {
1671                 NV_bytes anv;
1672                 SHIFT_BYTES(utf8, s, strend, anv.bytes, sizeof(anv.bytes),
1673                             datumtype, needs_swap);
1674                 if (!checksum)
1675                     mPUSHn(anv.nv);
1676                 else
1677                     cdouble += anv.nv;
1678             }
1679             break;
1680 #if defined(HAS_LONG_DOUBLE) && defined(USE_LONG_DOUBLE)
1681         case 'D':
1682             while (len-- > 0) {
1683                 ld_bytes aldouble;
1684                 SHIFT_BYTES(utf8, s, strend, aldouble.bytes,
1685                             sizeof(aldouble.bytes), datumtype, needs_swap);
1686                 /* The most common long double format, the x86 80-bit
1687                  * extended precision, has either 2 or 6 unused bytes,
1688                  * which may contain garbage, which may contain
1689                  * unintentional data.  While we do zero the bytes of
1690                  * the long double data in pack(), here in unpack() we
1691                  * don't, because it's really hard to envision that
1692                  * reading the long double off aldouble would be
1693                  * affected by the unused bytes.
1694                  *
1695                  * Note that trying to unpack 'long doubles' of 'long
1696                  * doubles' packed in another system is in the general
1697                  * case doomed without having more detail. */
1698                 if (!checksum)
1699                     mPUSHn(aldouble.ld);
1700                 else
1701                     cdouble += aldouble.ld;
1702             }
1703             break;
1704 #endif
1705         case 'u':
1706             if (!checksum) {
1707                 const STRLEN l = (STRLEN) (strend - s) * 3 / 4;
1708                 sv = sv_2mortal(newSV(l));
1709                 if (l) SvPOK_on(sv);
1710             }
1711
1712             /* Note that all legal uuencoded strings are ASCII printables, so
1713              * have the same representation under UTF-8 vs not.  This means we
1714              * can ignore UTF8ness on legal input.  For illegal we stop at the
1715              * first failure, and don't report where/what that is, so again we
1716              * can ignore UTF8ness */
1717
1718             while (s < strend && *s != ' ' && ISUUCHAR(*s)) {
1719                 I32 a, b, c, d;
1720                 char hunk[3];
1721
1722                 len = PL_uudmap[*(U8*)s++] & 077;
1723                 while (len > 0) {
1724                     if (s < strend && ISUUCHAR(*s))
1725                         a = PL_uudmap[*(U8*)s++] & 077;
1726                     else
1727                         a = 0;
1728                     if (s < strend && ISUUCHAR(*s))
1729                         b = PL_uudmap[*(U8*)s++] & 077;
1730                     else
1731                         b = 0;
1732                     if (s < strend && ISUUCHAR(*s))
1733                         c = PL_uudmap[*(U8*)s++] & 077;
1734                     else
1735                         c = 0;
1736                     if (s < strend && ISUUCHAR(*s))
1737                         d = PL_uudmap[*(U8*)s++] & 077;
1738                     else
1739                         d = 0;
1740                     hunk[0] = (char)((a << 2) | (b >> 4));
1741                     hunk[1] = (char)((b << 4) | (c >> 2));
1742                     hunk[2] = (char)((c << 6) | d);
1743                     if (!checksum)
1744                         sv_catpvn(sv, hunk, (len > 3) ? 3 : len);
1745                     len -= 3;
1746                 }
1747                 if (*s == '\n')
1748                     s++;
1749                 else    /* possible checksum byte */
1750                     if (s + 1 < strend && s[1] == '\n')
1751                         s += 2;
1752             }
1753             if (!checksum)
1754                 XPUSHs(sv);
1755             break;
1756         } /* End of switch */
1757
1758         if (checksum) {
1759             if (strchr("fFdD", TYPE_NO_MODIFIERS(datumtype)) ||
1760               (checksum > bits_in_uv &&
1761                strchr("cCsSiIlLnNUWvVqQjJ", TYPE_NO_MODIFIERS(datumtype))) ) {
1762                 NV trouble, anv;
1763
1764                 anv = (NV) (1 << (checksum & 15));
1765                 while (checksum >= 16) {
1766                     checksum -= 16;
1767                     anv *= 65536.0;
1768                 }
1769                 while (cdouble < 0.0)
1770                     cdouble += anv;
1771                 cdouble = Perl_modf(cdouble / anv, &trouble);
1772 #ifdef LONGDOUBLE_DOUBLEDOUBLE
1773                 /* Workaround for powerpc doubledouble modfl bug:
1774                  * close to 1.0L and -1.0L cdouble is 0, and trouble
1775                  * is cdouble / anv. */
1776                 if (trouble != Perl_ceil(trouble)) {
1777                   cdouble = trouble;
1778                   if (cdouble >  1.0L) cdouble -= 1.0L;
1779                   if (cdouble < -1.0L) cdouble += 1.0L;
1780                 }
1781 #endif
1782                 cdouble *= anv;
1783                 sv = newSVnv(cdouble);
1784             }
1785             else {
1786                 if (checksum < bits_in_uv) {
1787                     UV mask = ((UV)1 << checksum) - 1;
1788                     cuv &= mask;
1789                 }
1790                 sv = newSVuv(cuv);
1791             }
1792             mXPUSHs(sv);
1793             checksum = 0;
1794         }
1795
1796         if (symptr->flags & FLAG_SLASH){
1797             if (SP - PL_stack_base - start_sp_offset <= 0)
1798                 break;
1799             if( next_symbol(symptr) ){
1800               if( symptr->howlen == e_number )
1801                 Perl_croak(aTHX_ "Count after length/code in unpack" );
1802               if( beyond ){
1803                 /* ...end of char buffer then no decent length available */
1804                 Perl_croak(aTHX_ "length/code after end of string in unpack" );
1805               } else {
1806                 /* take top of stack (hope it's numeric) */
1807                 len = POPi;
1808                 if( len < 0 )
1809                     Perl_croak(aTHX_ "Negative '/' count in unpack" );
1810               }
1811             } else {
1812                 Perl_croak(aTHX_ "Code missing after '/' in unpack" );
1813             }
1814             datumtype = symptr->code;
1815             explicit_length = FALSE;
1816             goto redo_switch;
1817         }
1818     }
1819
1820     if (new_s)
1821         *new_s = s;
1822     PUTBACK;
1823     return SP - PL_stack_base - start_sp_offset;
1824 }
1825
1826 PP(pp_unpack)
1827 {
1828     dSP;
1829     dPOPPOPssrl;
1830     U8 gimme = GIMME_V;
1831     STRLEN llen;
1832     STRLEN rlen;
1833     const char *pat = SvPV_const(left,  llen);
1834     const char *s   = SvPV_const(right, rlen);
1835     const char *strend = s + rlen;
1836     const char *patend = pat + llen;
1837     I32 cnt;
1838
1839     PUTBACK;
1840     cnt = unpackstring(pat, patend, s, strend,
1841                      ((gimme == G_SCALAR) ? FLAG_UNPACK_ONLY_ONE : 0)
1842                      | (DO_UTF8(right) ? FLAG_DO_UTF8 : 0));
1843
1844     SPAGAIN;
1845     if ( !cnt && gimme == G_SCALAR )
1846        PUSHs(&PL_sv_undef);
1847     RETURN;
1848 }
1849
1850 STATIC U8 *
1851 doencodes(U8 *h, const U8 *s, I32 len)
1852 {
1853     *h++ = PL_uuemap[len];
1854     while (len > 2) {
1855         *h++ = PL_uuemap[(077 & (s[0] >> 2))];
1856         *h++ = PL_uuemap[(077 & (((s[0] << 4) & 060) | ((s[1] >> 4) & 017)))];
1857         *h++ = PL_uuemap[(077 & (((s[1] << 2) & 074) | ((s[2] >> 6) & 03)))];
1858         *h++ = PL_uuemap[(077 & (s[2] & 077))];
1859         s += 3;
1860         len -= 3;
1861     }
1862     if (len > 0) {
1863         const U8 r = (len > 1 ? s[1] : '\0');
1864         *h++ = PL_uuemap[(077 & (s[0] >> 2))];
1865         *h++ = PL_uuemap[(077 & (((s[0] << 4) & 060) | ((r >> 4) & 017)))];
1866         *h++ = PL_uuemap[(077 & ((r << 2) & 074))];
1867         *h++ = PL_uuemap[0];
1868     }
1869     *h++ = '\n';
1870     return h;
1871 }
1872
1873 STATIC SV *
1874 S_is_an_int(pTHX_ const char *s, STRLEN l)
1875 {
1876   SV *result = newSVpvn(s, l);
1877   char *const result_c = SvPV_nolen(result);    /* convenience */
1878   char *out = result_c;
1879   bool skip = 1;
1880   bool ignore = 0;
1881
1882   PERL_ARGS_ASSERT_IS_AN_INT;
1883
1884   while (*s) {
1885     switch (*s) {
1886     case ' ':
1887       break;
1888     case '+':
1889       if (!skip) {
1890         SvREFCNT_dec(result);
1891         return (NULL);
1892       }
1893       break;
1894     case '0':
1895     case '1':
1896     case '2':
1897     case '3':
1898     case '4':
1899     case '5':
1900     case '6':
1901     case '7':
1902     case '8':
1903     case '9':
1904       skip = 0;
1905       if (!ignore) {
1906         *(out++) = *s;
1907       }
1908       break;
1909     case '.':
1910       ignore = 1;
1911       break;
1912     default:
1913       SvREFCNT_dec(result);
1914       return (NULL);
1915     }
1916     s++;
1917   }
1918   *(out++) = '\0';
1919   SvCUR_set(result, out - result_c);
1920   return (result);
1921 }
1922
1923 /* pnum must be '\0' terminated */
1924 STATIC int
1925 S_div128(pTHX_ SV *pnum, bool *done)
1926 {
1927     STRLEN len;
1928     char * const s = SvPV(pnum, len);
1929     char *t = s;
1930     int m = 0;
1931
1932     PERL_ARGS_ASSERT_DIV128;
1933
1934     *done = 1;
1935     while (*t) {
1936         const int i = m * 10 + (*t - '0');
1937         const int r = (i >> 7); /* r < 10 */
1938         m = i & 0x7F;
1939         if (r) {
1940             *done = 0;
1941         }
1942         *(t++) = '0' + r;
1943     }
1944     *(t++) = '\0';
1945     SvCUR_set(pnum, (STRLEN) (t - s));
1946     return (m);
1947 }
1948
1949 /*
1950 =for apidoc packlist
1951
1952 The engine implementing C<pack()> Perl function.
1953
1954 =cut
1955 */
1956
1957 void
1958 Perl_packlist(pTHX_ SV *cat, const char *pat, const char *patend, SV **beglist, SV **endlist )
1959 {
1960     tempsym_t sym;
1961
1962     PERL_ARGS_ASSERT_PACKLIST;
1963
1964     TEMPSYM_INIT(&sym, pat, patend, FLAG_PACK);
1965
1966     /* We're going to do changes through SvPVX(cat). Make sure it's valid.
1967        Also make sure any UTF8 flag is loaded */
1968     SvPV_force_nolen(cat);
1969     if (DO_UTF8(cat))
1970         sym.flags |= FLAG_PARSE_UTF8 | FLAG_DO_UTF8;
1971
1972     (void)pack_rec( cat, &sym, beglist, endlist );
1973 }
1974
1975 /* like sv_utf8_upgrade, but also repoint the group start markers */
1976 STATIC void
1977 marked_upgrade(pTHX_ SV *sv, tempsym_t *sym_ptr) {
1978     STRLEN len;
1979     tempsym_t *group;
1980     const char *from_ptr, *from_start, *from_end, **marks, **m;
1981     char *to_start, *to_ptr;
1982
1983     if (SvUTF8(sv)) return;
1984
1985     from_start = SvPVX_const(sv);
1986     from_end = from_start + SvCUR(sv);
1987     for (from_ptr = from_start; from_ptr < from_end; from_ptr++)
1988         if (!NATIVE_BYTE_IS_INVARIANT(*from_ptr)) break;
1989     if (from_ptr == from_end) {
1990         /* Simple case: no character needs to be changed */
1991         SvUTF8_on(sv);
1992         return;
1993     }
1994
1995     len = (from_end-from_ptr)*UTF8_EXPAND+(from_ptr-from_start)+1;
1996     Newx(to_start, len, char);
1997     Copy(from_start, to_start, from_ptr-from_start, char);
1998     to_ptr = to_start + (from_ptr-from_start);
1999
2000     Newx(marks, sym_ptr->level+2, const char *);
2001     for (group=sym_ptr; group; group = group->previous)
2002         marks[group->level] = from_start + group->strbeg;
2003     marks[sym_ptr->level+1] = from_end+1;
2004     for (m = marks; *m < from_ptr; m++)
2005         *m = to_start + (*m-from_start);
2006
2007     for (;from_ptr < from_end; from_ptr++) {
2008         while (*m == from_ptr) *m++ = to_ptr;
2009         to_ptr = (char *) uvchr_to_utf8((U8 *) to_ptr, *(U8 *) from_ptr);
2010     }
2011     *to_ptr = 0;
2012
2013     while (*m == from_ptr) *m++ = to_ptr;
2014     if (m != marks + sym_ptr->level+1) {
2015         Safefree(marks);
2016         Safefree(to_start);
2017         Perl_croak(aTHX_ "panic: marks beyond string end, m=%p, marks=%p, "
2018                    "level=%d", m, marks, sym_ptr->level);
2019     }
2020     for (group=sym_ptr; group; group = group->previous)
2021         group->strbeg = marks[group->level] - to_start;
2022     Safefree(marks);
2023
2024     if (SvOOK(sv)) {
2025         if (SvIVX(sv)) {
2026             SvLEN_set(sv, SvLEN(sv) + SvIVX(sv));
2027             from_start -= SvIVX(sv);
2028             SvIV_set(sv, 0);
2029         }
2030         SvFLAGS(sv) &= ~SVf_OOK;
2031     }
2032     if (SvLEN(sv) != 0)
2033         Safefree(from_start);
2034     SvPV_set(sv, to_start);
2035     SvCUR_set(sv, to_ptr - to_start);
2036     SvLEN_set(sv, len);
2037     SvUTF8_on(sv);
2038 }
2039
2040 /* Exponential string grower. Makes string extension effectively O(n)
2041    needed says how many extra bytes we need (not counting the final '\0')
2042    Only grows the string if there is an actual lack of space
2043 */
2044 STATIC char *
2045 S_sv_exp_grow(pTHX_ SV *sv, STRLEN needed) {
2046     const STRLEN cur = SvCUR(sv);
2047     const STRLEN len = SvLEN(sv);
2048     STRLEN extend;
2049
2050     PERL_ARGS_ASSERT_SV_EXP_GROW;
2051
2052     if (len - cur > needed) return SvPVX(sv);
2053     extend = needed > len ? needed : len;
2054     return SvGROW(sv, len+extend+1);
2055 }
2056
2057 static SV *
2058 S_sv_check_infnan(pTHX_ SV *sv, I32 datumtype)
2059 {
2060     SvGETMAGIC(sv);
2061     if (UNLIKELY(SvAMAGIC(sv)))
2062         sv = sv_2num(sv);
2063     if (UNLIKELY(isinfnansv(sv))) {
2064         const I32 c = TYPE_NO_MODIFIERS(datumtype);
2065         const NV nv = SvNV_nomg(sv);
2066         if (c == 'w')
2067             Perl_croak(aTHX_ "Cannot compress %" NVgf " in pack", nv);
2068         else
2069             Perl_croak(aTHX_ "Cannot pack %" NVgf " with '%c'", nv, (int) c);
2070     }
2071     return sv;
2072 }
2073
2074 #define SvIV_no_inf(sv,d) \
2075         ((sv) = S_sv_check_infnan(aTHX_ sv,d), SvIV_nomg(sv))
2076 #define SvUV_no_inf(sv,d) \
2077         ((sv) = S_sv_check_infnan(aTHX_ sv,d), SvUV_nomg(sv))
2078
2079 STATIC
2080 SV **
2081 S_pack_rec(pTHX_ SV *cat, tempsym_t* symptr, SV **beglist, SV **endlist )
2082 {
2083     tempsym_t lookahead;
2084     I32 items  = endlist - beglist;
2085     bool found = next_symbol(symptr);
2086     bool utf8 = (symptr->flags & FLAG_PARSE_UTF8) ? 1 : 0;
2087     bool warn_utf8 = ckWARN(WARN_UTF8);
2088     char* from;
2089
2090     PERL_ARGS_ASSERT_PACK_REC;
2091
2092     if (symptr->level == 0 && found && symptr->code == 'U') {
2093         marked_upgrade(aTHX_ cat, symptr);
2094         symptr->flags |= FLAG_DO_UTF8;
2095         utf8 = 0;
2096     }
2097     symptr->strbeg = SvCUR(cat);
2098
2099     while (found) {
2100         SV *fromstr;
2101         STRLEN fromlen;
2102         I32 len;
2103         SV *lengthcode = NULL;
2104         I32 datumtype = symptr->code;
2105         howlen_t howlen = symptr->howlen;
2106         char *start = SvPVX(cat);
2107         char *cur   = start + SvCUR(cat);
2108         bool needs_swap;
2109
2110 #define NEXTFROM (lengthcode ? lengthcode : items > 0 ? (--items, *beglist++) : &PL_sv_no)
2111 #define PEEKFROM (lengthcode ? lengthcode : items > 0 ? *beglist : &PL_sv_no)
2112
2113         switch (howlen) {
2114           case e_star:
2115             len = strchr("@Xxu", TYPE_NO_MODIFIERS(datumtype)) ?
2116                 0 : items;
2117             break;
2118           default:
2119             /* e_no_len and e_number */
2120             len = symptr->length;
2121             break;
2122         }
2123
2124         if (len) {
2125             packprops_t props = packprops[TYPE_NO_ENDIANNESS(datumtype)];
2126
2127             if (props && !(props & PACK_SIZE_UNPREDICTABLE)) {
2128                 /* We can process this letter. */
2129                 STRLEN size = props & PACK_SIZE_MASK;
2130                 GROWING(utf8, cat, start, cur, (STRLEN) len * size);
2131             }
2132         }
2133
2134         /* Look ahead for next symbol. Do we have code/code? */
2135         lookahead = *symptr;
2136         found = next_symbol(&lookahead);
2137         if (symptr->flags & FLAG_SLASH) {
2138             IV count;
2139             if (!found) Perl_croak(aTHX_ "Code missing after '/' in pack");
2140             if (strchr("aAZ", lookahead.code)) {
2141                 if (lookahead.howlen == e_number) count = lookahead.length;
2142                 else {
2143                     if (items > 0) {
2144                         count = sv_len_utf8(*beglist);
2145                     }
2146                     else count = 0;
2147                     if (lookahead.code == 'Z') count++;
2148                 }
2149             } else {
2150                 if (lookahead.howlen == e_number && lookahead.length < items)
2151                     count = lookahead.length;
2152                 else count = items;
2153             }
2154             lookahead.howlen = e_number;
2155             lookahead.length = count;
2156             lengthcode = sv_2mortal(newSViv(count));
2157         }
2158
2159         needs_swap = NEEDS_SWAP(datumtype);
2160
2161         /* Code inside the switch must take care to properly update
2162            cat (CUR length and '\0' termination) if it updated *cur and
2163            doesn't simply leave using break */
2164         switch (TYPE_NO_ENDIANNESS(datumtype)) {
2165         default:
2166             Perl_croak(aTHX_ "Invalid type '%c' in pack",
2167                        (int) TYPE_NO_MODIFIERS(datumtype));
2168         case '%':
2169             Perl_croak(aTHX_ "'%%' may not be used in pack");
2170
2171         case '.' | TYPE_IS_SHRIEKING:
2172         case '.':
2173             if (howlen == e_star) from = start;
2174             else if (len == 0) from = cur;
2175             else {
2176                 tempsym_t *group = symptr;
2177
2178                 while (--len && group) group = group->previous;
2179                 from = group ? start + group->strbeg : start;
2180             }
2181             fromstr = NEXTFROM;
2182             len = SvIV_no_inf(fromstr, datumtype);
2183             goto resize;
2184         case '@' | TYPE_IS_SHRIEKING:
2185         case '@':
2186             from = start + symptr->strbeg;
2187           resize:
2188             if (utf8  && !(datumtype & TYPE_IS_SHRIEKING))
2189                 if (len >= 0) {
2190                     while (len && from < cur) {
2191                         from += UTF8SKIP(from);
2192                         len--;
2193                     }
2194                     if (from > cur)
2195                         Perl_croak(aTHX_ "Malformed UTF-8 string in pack");
2196                     if (len) {
2197                         /* Here we know from == cur */
2198                       grow:
2199                         GROWING(0, cat, start, cur, len);
2200                         Zero(cur, len, char);
2201                         cur += len;
2202                     } else if (from < cur) {
2203                         len = cur - from;
2204                         goto shrink;
2205                     } else goto no_change;
2206                 } else {
2207                     cur = from;
2208                     len = -len;
2209                     goto utf8_shrink;
2210                 }
2211             else {
2212                 len -= cur - from;
2213                 if (len > 0) goto grow;
2214                 if (len == 0) goto no_change;
2215                 len = -len;
2216                 goto shrink;
2217             }
2218             break;
2219
2220         case '(': {
2221             tempsym_t savsym = *symptr;
2222             U32 group_modifiers = TYPE_MODIFIERS(datumtype & ~symptr->flags);
2223             symptr->flags |= group_modifiers;
2224             symptr->patend = savsym.grpend;
2225             symptr->level++;
2226             symptr->previous = &lookahead;
2227             while (len--) {
2228                 U32 was_utf8;
2229                 if (utf8) symptr->flags |=  FLAG_PARSE_UTF8;
2230                 else      symptr->flags &= ~FLAG_PARSE_UTF8;
2231                 was_utf8 = SvUTF8(cat);
2232                 symptr->patptr = savsym.grpbeg;
2233                 beglist = pack_rec(cat, symptr, beglist, endlist);
2234                 if (SvUTF8(cat) != was_utf8)
2235                     /* This had better be an upgrade while in utf8==0 mode */
2236                     utf8 = 1;
2237
2238                 if (savsym.howlen == e_star && beglist == endlist)
2239                     break;              /* No way to continue */
2240             }
2241             items = endlist - beglist;
2242             lookahead.flags  = symptr->flags & ~group_modifiers;
2243             goto no_change;
2244         }
2245         case 'X' | TYPE_IS_SHRIEKING:
2246             if (!len)                   /* Avoid division by 0 */
2247                 len = 1;
2248             if (utf8) {
2249                 char *hop, *last;
2250                 I32 l = len;
2251                 hop = last = start;
2252                 while (hop < cur) {
2253                     hop += UTF8SKIP(hop);
2254                     if (--l == 0) {
2255                         last = hop;
2256                         l = len;
2257                     }
2258                 }
2259                 if (last > cur)
2260                     Perl_croak(aTHX_ "Malformed UTF-8 string in pack");
2261                 cur = last;
2262                 break;
2263             }
2264             len = (cur-start) % len;
2265             /* FALLTHROUGH */
2266         case 'X':
2267             if (utf8) {
2268                 if (len < 1) goto no_change;
2269               utf8_shrink:
2270                 while (len > 0) {
2271                     if (cur <= start)
2272                         Perl_croak(aTHX_ "'%c' outside of string in pack",
2273                                    (int) TYPE_NO_MODIFIERS(datumtype));
2274                     while (--cur, UTF8_IS_CONTINUATION(*cur)) {
2275                         if (cur <= start)
2276                             Perl_croak(aTHX_ "'%c' outside of string in pack",
2277                                        (int) TYPE_NO_MODIFIERS(datumtype));
2278                     }
2279                     len--;
2280                 }
2281             } else {
2282               shrink:
2283                 if (cur - start < len)
2284                     Perl_croak(aTHX_ "'%c' outside of string in pack",
2285                                (int) TYPE_NO_MODIFIERS(datumtype));
2286                 cur -= len;
2287             }
2288             if (cur < start+symptr->strbeg) {
2289                 /* Make sure group starts don't point into the void */
2290                 tempsym_t *group;
2291                 const STRLEN length = cur-start;
2292                 for (group = symptr;
2293                      group && length < group->strbeg;
2294                      group = group->previous) group->strbeg = length;
2295                 lookahead.strbeg = length;
2296             }
2297             break;
2298         case 'x' | TYPE_IS_SHRIEKING: {
2299             I32 ai32;
2300             if (!len)                   /* Avoid division by 0 */
2301                 len = 1;
2302             if (utf8) ai32 = utf8_length((U8 *) start, (U8 *) cur) % len;
2303             else      ai32 = (cur - start) % len;
2304             if (ai32 == 0) goto no_change;
2305             len -= ai32;
2306         }
2307         /* FALLTHROUGH */
2308         case 'x':
2309             goto grow;
2310         case 'A':
2311         case 'Z':
2312         case 'a': {
2313             const char *aptr;
2314
2315             fromstr = NEXTFROM;
2316             aptr = SvPV_const(fromstr, fromlen);
2317             if (DO_UTF8(fromstr)) {
2318                 const char *end, *s;
2319
2320                 if (!utf8 && !SvUTF8(cat)) {
2321                     marked_upgrade(aTHX_ cat, symptr);
2322                     lookahead.flags |= FLAG_DO_UTF8;
2323                     lookahead.strbeg = symptr->strbeg;
2324                     utf8 = 1;
2325                     start = SvPVX(cat);
2326                     cur = start + SvCUR(cat);
2327                 }
2328                 if (howlen == e_star) {
2329                     if (utf8) goto string_copy;
2330                     len = fromlen+1;
2331                 }
2332                 s = aptr;
2333                 end = aptr + fromlen;
2334                 fromlen = datumtype == 'Z' ? len-1 : len;
2335                 while ((I32) fromlen > 0 && s < end) {
2336                     s += UTF8SKIP(s);
2337                     fromlen--;
2338                 }
2339                 if (s > end)
2340                     Perl_croak(aTHX_ "Malformed UTF-8 string in pack");
2341                 if (utf8) {
2342                     len = fromlen;
2343                     if (datumtype == 'Z') len++;
2344                     fromlen = s-aptr;
2345                     len += fromlen;
2346
2347                     goto string_copy;
2348                 }
2349                 fromlen = len - fromlen;
2350                 if (datumtype == 'Z') fromlen--;
2351                 if (howlen == e_star) {
2352                     len = fromlen;
2353                     if (datumtype == 'Z') len++;
2354                 }
2355                 GROWING(0, cat, start, cur, len);
2356                 if (!S_utf8_to_bytes(aTHX_ &aptr, end, cur, fromlen,
2357                                   datumtype | TYPE_IS_PACK))
2358                     Perl_croak(aTHX_ "panic: predicted utf8 length not available, "
2359                                "for '%c', aptr=%p end=%p cur=%p, fromlen=%" UVuf,
2360                                (int)datumtype, aptr, end, cur, (UV)fromlen);
2361                 cur += fromlen;
2362                 len -= fromlen;
2363             } else if (utf8) {
2364                 if (howlen == e_star) {
2365                     len = fromlen;
2366                     if (datumtype == 'Z') len++;
2367                 }
2368                 if (len <= (I32) fromlen) {
2369                     fromlen = len;
2370                     if (datumtype == 'Z' && fromlen > 0) fromlen--;
2371                 }
2372                 /* assumes a byte expands to at most UTF8_EXPAND bytes on
2373                    upgrade, so:
2374                    expected_length <= from_len*UTF8_EXPAND + (len-from_len) */
2375                 GROWING(0, cat, start, cur, fromlen*(UTF8_EXPAND-1)+len);
2376                 len -= fromlen;
2377                 while (fromlen > 0) {
2378                     cur = (char *) uvchr_to_utf8((U8 *) cur, * (U8 *) aptr);
2379                     aptr++;
2380                     fromlen--;
2381                 }
2382             } else {
2383               string_copy:
2384                 if (howlen == e_star) {
2385                     len = fromlen;
2386                     if (datumtype == 'Z') len++;
2387                 }
2388                 if (len <= (I32) fromlen) {
2389                     fromlen = len;
2390                     if (datumtype == 'Z' && fromlen > 0) fromlen--;
2391                 }
2392                 GROWING(0, cat, start, cur, len);
2393                 Copy(aptr, cur, fromlen, char);
2394                 cur += fromlen;
2395                 len -= fromlen;
2396             }
2397             memset(cur, datumtype == 'A' ? ' ' : '\0', len);
2398             cur += len;
2399             SvTAINT(cat);
2400             break;
2401         }
2402         case 'B':
2403         case 'b': {
2404             const char *str, *end;
2405             I32 l, field_len;
2406             U8 bits;
2407             bool utf8_source;
2408             U32 utf8_flags;
2409
2410             fromstr = NEXTFROM;
2411             str = SvPV_const(fromstr, fromlen);
2412             end = str + fromlen;
2413             if (DO_UTF8(fromstr)) {
2414                 utf8_source = TRUE;
2415                 utf8_flags  = warn_utf8 ? 0 : UTF8_ALLOW_ANY;
2416             } else {
2417                 utf8_source = FALSE;
2418                 utf8_flags  = 0; /* Unused, but keep compilers happy */
2419             }
2420             if (howlen == e_star) len = fromlen;
2421             field_len = (len+7)/8;
2422             GROWING(utf8, cat, start, cur, field_len);
2423             if (len > (I32)fromlen) len = fromlen;
2424             bits = 0;
2425             l = 0;
2426             if (datumtype == 'B')
2427                 while (l++ < len) {
2428                     if (utf8_source) {
2429                         UV val = 0;
2430                         NEXT_UNI_VAL(val, cur, str, end, utf8_flags);
2431                         bits |= val & 1;
2432                     } else bits |= *str++ & 1;
2433                     if (l & 7) bits <<= 1;
2434                     else {
2435                         PUSH_BYTE(utf8, cur, bits);
2436                         bits = 0;
2437                     }
2438                 }
2439             else
2440                 /* datumtype == 'b' */
2441                 while (l++ < len) {
2442                     if (utf8_source) {
2443                         UV val = 0;
2444                         NEXT_UNI_VAL(val, cur, str, end, utf8_flags);
2445                         if (val & 1) bits |= 0x80;
2446                     } else if (*str++ & 1)
2447                         bits |= 0x80;
2448                     if (l & 7) bits >>= 1;
2449                     else {
2450                         PUSH_BYTE(utf8, cur, bits);
2451                         bits = 0;
2452                     }
2453                 }
2454             l--;
2455             if (l & 7) {
2456                 if (datumtype == 'B')
2457                     bits <<= 7 - (l & 7);
2458                 else
2459                     bits >>= 7 - (l & 7);
2460                 PUSH_BYTE(utf8, cur, bits);
2461                 l += 7;
2462             }
2463             /* Determine how many chars are left in the requested field */
2464             l /= 8;
2465             if (howlen == e_star) field_len = 0;
2466             else field_len -= l;
2467             Zero(cur, field_len, char);
2468             cur += field_len;
2469             break;
2470         }
2471         case 'H':
2472         case 'h': {
2473             const char *str, *end;
2474             I32 l, field_len;
2475             U8 bits;
2476             bool utf8_source;
2477             U32 utf8_flags;
2478
2479             fromstr = NEXTFROM;
2480             str = SvPV_const(fromstr, fromlen);
2481             end = str + fromlen;
2482             if (DO_UTF8(fromstr)) {
2483                 utf8_source = TRUE;
2484                 utf8_flags  = warn_utf8 ? 0 : UTF8_ALLOW_ANY;
2485             } else {
2486                 utf8_source = FALSE;
2487                 utf8_flags  = 0; /* Unused, but keep compilers happy */
2488             }
2489             if (howlen == e_star) len = fromlen;
2490             field_len = (len+1)/2;
2491             GROWING(utf8, cat, start, cur, field_len);
2492             if (!utf8_source && len > (I32)fromlen) len = fromlen;
2493             bits = 0;
2494             l = 0;
2495             if (datumtype == 'H')
2496                 while (l++ < len) {
2497                     if (utf8_source) {
2498                         UV val = 0;
2499                         NEXT_UNI_VAL(val, cur, str, end, utf8_flags);
2500                         if (val < 256 && isALPHA(val))
2501                             bits |= (val + 9) & 0xf;
2502                         else
2503                             bits |= val & 0xf;
2504                     } else if (isALPHA(*str))
2505                         bits |= (*str++ + 9) & 0xf;
2506                     else
2507                         bits |= *str++ & 0xf;
2508                     if (l & 1) bits <<= 4;
2509                     else {
2510                         PUSH_BYTE(utf8, cur, bits);
2511                         bits = 0;
2512                     }
2513                 }
2514             else
2515                 while (l++ < len) {
2516                     if (utf8_source) {
2517                         UV val = 0;
2518                         NEXT_UNI_VAL(val, cur, str, end, utf8_flags);
2519                         if (val < 256 && isALPHA(val))
2520                             bits |= ((val + 9) & 0xf) << 4;
2521                         else
2522                             bits |= (val & 0xf) << 4;
2523                     } else if (isALPHA(*str))
2524                         bits |= ((*str++ + 9) & 0xf) << 4;
2525                     else
2526                         bits |= (*str++ & 0xf) << 4;
2527                     if (l & 1) bits >>= 4;
2528                     else {
2529                         PUSH_BYTE(utf8, cur, bits);
2530                         bits = 0;
2531                     }
2532                 }
2533             l--;
2534             if (l & 1) {
2535                 PUSH_BYTE(utf8, cur, bits);
2536                 l++;
2537             }
2538             /* Determine how many chars are left in the requested field */
2539             l /= 2;
2540             if (howlen == e_star) field_len = 0;
2541             else field_len -= l;
2542             Zero(cur, field_len, char);
2543             cur += field_len;
2544             break;
2545         }
2546         case 'c':
2547             while (len-- > 0) {
2548                 IV aiv;
2549                 fromstr = NEXTFROM;
2550                 aiv = SvIV_no_inf(fromstr, datumtype);
2551                 if ((-128 > aiv || aiv > 127))
2552                     Perl_ck_warner(aTHX_ packWARN(WARN_PACK),
2553                                    "Character in 'c' format wrapped in pack");
2554                 PUSH_BYTE(utf8, cur, (U8)(aiv & 0xff));
2555             }
2556             break;
2557         case 'C':
2558             if (len == 0) {
2559                 utf8 = (symptr->flags & FLAG_DO_UTF8) ? 1 : 0;
2560                 break;
2561             }
2562             while (len-- > 0) {
2563                 IV aiv;
2564                 fromstr = NEXTFROM;
2565                 aiv = SvIV_no_inf(fromstr, datumtype);
2566                 if ((0 > aiv || aiv > 0xff))
2567                     Perl_ck_warner(aTHX_ packWARN(WARN_PACK),
2568                                    "Character in 'C' format wrapped in pack");
2569                 PUSH_BYTE(utf8, cur, (U8)(aiv & 0xff));
2570             }
2571             break;
2572         case 'W': {
2573             char *end;
2574             U8 in_bytes = (U8)IN_BYTES;
2575
2576             end = start+SvLEN(cat)-1;
2577             if (utf8) end -= UTF8_MAXLEN-1;
2578             while (len-- > 0) {
2579                 UV auv;
2580                 fromstr = NEXTFROM;
2581                 auv = SvUV_no_inf(fromstr, datumtype);
2582                 if (in_bytes) auv = auv % 0x100;
2583                 if (utf8) {
2584                   W_utf8:
2585                     if (cur > end) {
2586                         *cur = '\0';
2587                         SvCUR_set(cat, cur - start);
2588
2589                         GROWING(0, cat, start, cur, len+UTF8_MAXLEN);
2590                         end = start+SvLEN(cat)-UTF8_MAXLEN;
2591                     }
2592                     cur = (char *) uvchr_to_utf8_flags((U8 *) cur,
2593                                                        auv,
2594                                                        warn_utf8 ?
2595                                                        0 : UNICODE_ALLOW_ANY);
2596                 } else {
2597                     if (auv >= 0x100) {
2598                         if (!SvUTF8(cat)) {
2599                             *cur = '\0';
2600                             SvCUR_set(cat, cur - start);
2601                             marked_upgrade(aTHX_ cat, symptr);
2602                             lookahead.flags |= FLAG_DO_UTF8;
2603                             lookahead.strbeg = symptr->strbeg;
2604                             utf8 = 1;
2605                             start = SvPVX(cat);
2606                             cur = start + SvCUR(cat);
2607                             end = start+SvLEN(cat)-UTF8_MAXLEN;
2608                             goto W_utf8;
2609                         }
2610                         Perl_ck_warner(aTHX_ packWARN(WARN_PACK),
2611                                        "Character in 'W' format wrapped in pack");
2612                         auv &= 0xff;
2613                     }
2614                     if (cur >= end) {
2615                         *cur = '\0';
2616                         SvCUR_set(cat, cur - start);
2617                         GROWING(0, cat, start, cur, len+1);
2618                         end = start+SvLEN(cat)-1;
2619                     }
2620                     *(U8 *) cur++ = (U8)auv;
2621                 }
2622             }
2623             break;
2624         }
2625         case 'U': {
2626             char *end;
2627
2628             if (len == 0) {
2629                 if (!(symptr->flags & FLAG_DO_UTF8)) {
2630                     marked_upgrade(aTHX_ cat, symptr);
2631                     lookahead.flags |= FLAG_DO_UTF8;
2632                     lookahead.strbeg = symptr->strbeg;
2633                 }
2634                 utf8 = 0;
2635                 goto no_change;
2636             }
2637
2638             end = start+SvLEN(cat);
2639             if (!utf8) end -= UTF8_MAXLEN;
2640             while (len-- > 0) {
2641                 UV auv;
2642                 fromstr = NEXTFROM;
2643                 auv = SvUV_no_inf(fromstr, datumtype);
2644                 if (utf8) {
2645                     U8 buffer[UTF8_MAXLEN], *endb;
2646                     endb = uvchr_to_utf8_flags(buffer, UNI_TO_NATIVE(auv),
2647                                                warn_utf8 ?
2648                                                0 : UNICODE_ALLOW_ANY);
2649                     if (cur+(endb-buffer)*UTF8_EXPAND >= end) {
2650                         *cur = '\0';
2651                         SvCUR_set(cat, cur - start);
2652                         GROWING(0, cat, start, cur,
2653                                 len+(endb-buffer)*UTF8_EXPAND);
2654                         end = start+SvLEN(cat);
2655                     }
2656                     cur = my_bytes_to_utf8(buffer, endb-buffer, cur, 0);
2657                 } else {
2658                     if (cur >= end) {
2659                         *cur = '\0';
2660                         SvCUR_set(cat, cur - start);
2661                         GROWING(0, cat, start, cur, len+UTF8_MAXLEN);
2662                         end = start+SvLEN(cat)-UTF8_MAXLEN;
2663                     }
2664                     cur = (char *) uvchr_to_utf8_flags((U8 *) cur, UNI_TO_NATIVE(auv),
2665                                                        warn_utf8 ?
2666                                                        0 : UNICODE_ALLOW_ANY);
2667                 }
2668             }
2669             break;
2670         }
2671         /* Float and double added by gnb@melba.bby.oz.au  22/11/89 */
2672         case 'f':
2673             while (len-- > 0) {
2674                 float afloat;
2675                 NV anv;
2676                 fromstr = NEXTFROM;
2677                 anv = SvNV(fromstr);
2678 # if (defined(VMS) && !defined(_IEEE_FP)) || defined(DOUBLE_IS_VAX_FLOAT)
2679                 /* IEEE fp overflow shenanigans are unavailable on VAX and optional
2680                  * on Alpha; fake it if we don't have them.
2681                  */
2682                 if (anv > FLT_MAX)
2683                     afloat = FLT_MAX;
2684                 else if (anv < -FLT_MAX)
2685                     afloat = -FLT_MAX;
2686                 else afloat = (float)anv;
2687 # else
2688 #  if defined(NAN_COMPARE_BROKEN) && defined(Perl_isnan)
2689                 if(Perl_isnan(anv))
2690                     afloat = (float)NV_NAN;
2691                 else
2692 #  endif
2693 #  ifdef NV_INF
2694                 /* a simple cast to float is undefined if outside
2695                  * the range of values that can be represented */
2696                 afloat = (float)(anv >  FLT_MAX ?  NV_INF :
2697                                  anv < -FLT_MAX ? -NV_INF : anv);
2698 #  endif
2699 # endif
2700                 PUSH_VAR(utf8, cur, afloat, needs_swap);
2701             }
2702             break;
2703         case 'd':
2704             while (len-- > 0) {
2705                 double adouble;
2706                 NV anv;
2707                 fromstr = NEXTFROM;
2708                 anv = SvNV(fromstr);
2709 # if (defined(VMS) && !defined(_IEEE_FP)) || defined(DOUBLE_IS_VAX_FLOAT)
2710                 /* IEEE fp overflow shenanigans are unavailable on VAX and optional
2711                  * on Alpha; fake it if we don't have them.
2712                  */
2713                 if (anv > DBL_MAX)
2714                     adouble = DBL_MAX;
2715                 else if (anv < -DBL_MAX)
2716                     adouble = -DBL_MAX;
2717                 else adouble = (double)anv;
2718 # else
2719                 adouble = (double)anv;
2720 # endif
2721                 PUSH_VAR(utf8, cur, adouble, needs_swap);
2722             }
2723             break;
2724         case 'F': {
2725             NV_bytes anv;
2726             Zero(&anv, 1, NV); /* can be long double with unused bits */
2727             while (len-- > 0) {
2728                 fromstr = NEXTFROM;
2729 #ifdef __GNUC__
2730                 /* to work round a gcc/x86 bug; don't use SvNV */
2731                 anv.nv = sv_2nv(fromstr);
2732 #    if defined(LONGDOUBLE_X86_80_BIT) && defined(USE_LONG_DOUBLE) \
2733          && LONG_DOUBLESIZE > 10
2734                 /* GCC sometimes overwrites the padding in the
2735                    assignment above */
2736                 Zero(anv.bytes+10, sizeof(anv.bytes) - 10, U8);
2737 #    endif
2738 #else
2739                 anv.nv = SvNV(fromstr);
2740 #endif
2741                 PUSH_BYTES(utf8, cur, anv.bytes, sizeof(anv.bytes), needs_swap);
2742             }
2743             break;
2744         }
2745 #if defined(HAS_LONG_DOUBLE) && defined(USE_LONG_DOUBLE)
2746         case 'D': {
2747             ld_bytes aldouble;
2748             /* long doubles can have unused bits, which may be nonzero */
2749             Zero(&aldouble, 1, long double);
2750             while (len-- > 0) {
2751                 fromstr = NEXTFROM;
2752 #  ifdef __GNUC__
2753                 /* to work round a gcc/x86 bug; don't use SvNV */
2754                 aldouble.ld = (long double)sv_2nv(fromstr);
2755 #    if defined(LONGDOUBLE_X86_80_BIT) && LONG_DOUBLESIZE > 10
2756                 /* GCC sometimes overwrites the padding in the
2757                    assignment above */
2758                 Zero(aldouble.bytes+10, sizeof(aldouble.bytes) - 10, U8);
2759 #    endif
2760 #  else
2761                 aldouble.ld = (long double)SvNV(fromstr);
2762 #  endif
2763                 PUSH_BYTES(utf8, cur, aldouble.bytes, sizeof(aldouble.bytes),
2764                            needs_swap);
2765             }
2766             break;
2767         }
2768 #endif
2769         case 'n' | TYPE_IS_SHRIEKING:
2770         case 'n':
2771             while (len-- > 0) {
2772                 I16 ai16;
2773                 fromstr = NEXTFROM;
2774                 ai16 = (I16)SvIV_no_inf(fromstr, datumtype);
2775                 ai16 = PerlSock_htons(ai16);
2776                 PUSH16(utf8, cur, &ai16, FALSE);
2777             }
2778             break;
2779         case 'v' | TYPE_IS_SHRIEKING:
2780         case 'v':
2781             while (len-- > 0) {
2782                 I16 ai16;
2783                 fromstr = NEXTFROM;
2784                 ai16 = (I16)SvIV_no_inf(fromstr, datumtype);
2785                 ai16 = htovs(ai16);
2786                 PUSH16(utf8, cur, &ai16, FALSE);
2787             }
2788             break;
2789         case 'S' | TYPE_IS_SHRIEKING:
2790 #if SHORTSIZE != SIZE16
2791             while (len-- > 0) {
2792                 unsigned short aushort;
2793                 fromstr = NEXTFROM;
2794                 aushort = SvUV_no_inf(fromstr, datumtype);
2795                 PUSH_VAR(utf8, cur, aushort, needs_swap);
2796             }
2797             break;
2798 #else
2799             /* FALLTHROUGH */
2800 #endif
2801         case 'S':
2802             while (len-- > 0) {
2803                 U16 au16;
2804                 fromstr = NEXTFROM;
2805                 au16 = (U16)SvUV_no_inf(fromstr, datumtype);
2806                 PUSH16(utf8, cur, &au16, needs_swap);
2807             }
2808             break;
2809         case 's' | TYPE_IS_SHRIEKING:
2810 #if SHORTSIZE != SIZE16
2811             while (len-- > 0) {
2812                 short ashort;
2813                 fromstr = NEXTFROM;
2814                 ashort = SvIV_no_inf(fromstr, datumtype);
2815                 PUSH_VAR(utf8, cur, ashort, needs_swap);
2816             }
2817             break;
2818 #else
2819             /* FALLTHROUGH */
2820 #endif
2821         case 's':
2822             while (len-- > 0) {
2823                 I16 ai16;
2824                 fromstr = NEXTFROM;
2825                 ai16 = (I16)SvIV_no_inf(fromstr, datumtype);
2826                 PUSH16(utf8, cur, &ai16, needs_swap);
2827             }
2828             break;
2829         case 'I':
2830         case 'I' | TYPE_IS_SHRIEKING:
2831             while (len-- > 0) {
2832                 unsigned int auint;
2833                 fromstr = NEXTFROM;
2834                 auint = SvUV_no_inf(fromstr, datumtype);
2835                 PUSH_VAR(utf8, cur, auint, needs_swap);
2836             }
2837             break;
2838         case 'j':
2839             while (len-- > 0) {
2840                 IV aiv;
2841                 fromstr = NEXTFROM;
2842                 aiv = SvIV_no_inf(fromstr, datumtype);
2843                 PUSH_VAR(utf8, cur, aiv, needs_swap);
2844             }
2845             break;
2846         case 'J':
2847             while (len-- > 0) {
2848                 UV auv;
2849                 fromstr = NEXTFROM;
2850                 auv = SvUV_no_inf(fromstr, datumtype);
2851                 PUSH_VAR(utf8, cur, auv, needs_swap);
2852             }
2853             break;
2854         case 'w':
2855             while (len-- > 0) {
2856                 NV anv;
2857                 fromstr = NEXTFROM;
2858                 S_sv_check_infnan(aTHX_ fromstr, datumtype);
2859                 anv = SvNV_nomg(fromstr);
2860
2861                 if (anv < 0) {
2862                     *cur = '\0';
2863                     SvCUR_set(cat, cur - start);
2864                     Perl_croak(aTHX_ "Cannot compress negative numbers in pack");
2865                 }
2866
2867                 /* 0xFFFFFFFFFFFFFFFF may cast to 18446744073709551616.0,
2868                    which is == UV_MAX_P1. IOK is fine (instead of UV_only), as
2869                    any negative IVs will have already been got by the croak()
2870                    above. IOK is untrue for fractions, so we test them
2871                    against UV_MAX_P1.  */
2872                 if (SvIOK(fromstr) || anv < UV_MAX_P1) {
2873                     char   buf[(sizeof(UV)*CHAR_BIT)/7+1];
2874                     char  *in = buf + sizeof(buf);
2875                     UV     auv = SvUV_nomg(fromstr);
2876
2877                     do {
2878                         *--in = (char)((auv & 0x7f) | 0x80);
2879                         auv >>= 7;
2880                     } while (auv);
2881                     buf[sizeof(buf) - 1] &= 0x7f; /* clear continue bit */
2882                     PUSH_GROWING_BYTES(utf8, cat, start, cur,
2883                                        in, (buf + sizeof(buf)) - in);
2884                 } else if (SvPOKp(fromstr))
2885                     goto w_string;
2886                 else if (SvNOKp(fromstr)) {
2887                     /* 10**NV_MAX_10_EXP is the largest power of 10
2888                        so 10**(NV_MAX_10_EXP+1) is definitely unrepresentable
2889                        given 10**(NV_MAX_10_EXP+1) == 128 ** x solve for x:
2890                        x = (NV_MAX_10_EXP+1) * log (10) / log (128)
2891                        And with that many bytes only Inf can overflow.
2892                        Some C compilers are strict about integral constant
2893                        expressions so we conservatively divide by a slightly
2894                        smaller integer instead of multiplying by the exact
2895                        floating-point value.
2896                     */
2897 #ifdef NV_MAX_10_EXP
2898                     /* char   buf[1 + (int)((NV_MAX_10_EXP + 1) * 0.47456)]; -- invalid C */
2899                     char   buf[1 + (int)((NV_MAX_10_EXP + 1) / 2)]; /* valid C */
2900 #else
2901                     /* char   buf[1 + (int)((308 + 1) * 0.47456)]; -- invalid C */
2902                     char   buf[1 + (int)((308 + 1) / 2)]; /* valid C */
2903 #endif
2904                     char  *in = buf + sizeof(buf);
2905
2906                     anv = Perl_floor(anv);
2907                     do {
2908                         const NV next = Perl_floor(anv / 128);
2909                         if (in <= buf)  /* this cannot happen ;-) */
2910                             Perl_croak(aTHX_ "Cannot compress integer in pack");
2911                         *--in = (unsigned char)(anv - (next * 128)) | 0x80;
2912                         anv = next;
2913                     } while (anv > 0);
2914                     buf[sizeof(buf) - 1] &= 0x7f; /* clear continue bit */
2915                     PUSH_GROWING_BYTES(utf8, cat, start, cur,
2916                                        in, (buf + sizeof(buf)) - in);
2917                 } else {
2918                     const char     *from;
2919                     char           *result, *in;
2920                     SV             *norm;
2921                     STRLEN          len;
2922                     bool            done;
2923
2924                   w_string:
2925                     /* Copy string and check for compliance */
2926                     from = SvPV_nomg_const(fromstr, len);
2927                     if ((norm = is_an_int(from, len)) == NULL)
2928                         Perl_croak(aTHX_ "Can only compress unsigned integers in pack");
2929
2930                     Newx(result, len, char);
2931                     in = result + len;
2932                     done = FALSE;
2933                     while (!done) *--in = div128(norm, &done) | 0x80;
2934                     result[len - 1] &= 0x7F; /* clear continue bit */
2935                     PUSH_GROWING_BYTES(utf8, cat, start, cur,
2936                                        in, (result + len) - in);
2937                     Safefree(result);
2938                     SvREFCNT_dec(norm); /* free norm */
2939                 }
2940             }
2941             break;
2942         case 'i':
2943         case 'i' | TYPE_IS_SHRIEKING:
2944             while (len-- > 0) {
2945                 int aint;
2946                 fromstr = NEXTFROM;
2947                 aint = SvIV_no_inf(fromstr, datumtype);
2948                 PUSH_VAR(utf8, cur, aint, needs_swap);
2949             }
2950             break;
2951         case 'N' | TYPE_IS_SHRIEKING:
2952         case 'N':
2953             while (len-- > 0) {
2954                 U32 au32;
2955                 fromstr = NEXTFROM;
2956                 au32 = SvUV_no_inf(fromstr, datumtype);
2957                 au32 = PerlSock_htonl(au32);
2958                 PUSH32(utf8, cur, &au32, FALSE);
2959             }
2960             break;
2961         case 'V' | TYPE_IS_SHRIEKING:
2962         case 'V':
2963             while (len-- > 0) {
2964                 U32 au32;
2965                 fromstr = NEXTFROM;
2966                 au32 = SvUV_no_inf(fromstr, datumtype);
2967                 au32 = htovl(au32);
2968                 PUSH32(utf8, cur, &au32, FALSE);
2969             }
2970             break;
2971         case 'L' | TYPE_IS_SHRIEKING:
2972 #if LONGSIZE != SIZE32
2973             while (len-- > 0) {
2974                 unsigned long aulong;
2975                 fromstr = NEXTFROM;
2976                 aulong = SvUV_no_inf(fromstr, datumtype);
2977                 PUSH_VAR(utf8, cur, aulong, needs_swap);
2978             }
2979             break;
2980 #else
2981             /* Fall though! */
2982 #endif
2983         case 'L':
2984             while (len-- > 0) {
2985                 U32 au32;
2986                 fromstr = NEXTFROM;
2987                 au32 = SvUV_no_inf(fromstr, datumtype);
2988                 PUSH32(utf8, cur, &au32, needs_swap);
2989             }
2990             break;
2991         case 'l' | TYPE_IS_SHRIEKING:
2992 #if LONGSIZE != SIZE32
2993             while (len-- > 0) {
2994                 long along;
2995                 fromstr = NEXTFROM;
2996                 along = SvIV_no_inf(fromstr, datumtype);
2997                 PUSH_VAR(utf8, cur, along, needs_swap);
2998             }
2999             break;
3000 #else
3001             /* Fall though! */
3002 #endif
3003         case 'l':
3004             while (len-- > 0) {
3005                 I32 ai32;
3006                 fromstr = NEXTFROM;
3007                 ai32 = SvIV_no_inf(fromstr, datumtype);
3008                 PUSH32(utf8, cur, &ai32, needs_swap);
3009             }
3010             break;
3011 #if defined(HAS_QUAD) && IVSIZE >= 8
3012         case 'Q':
3013             while (len-- > 0) {
3014                 Uquad_t auquad;
3015                 fromstr = NEXTFROM;
3016                 auquad = (Uquad_t) SvUV_no_inf(fromstr, datumtype);
3017                 PUSH_VAR(utf8, cur, auquad, needs_swap);
3018             }
3019             break;
3020         case 'q':
3021             while (len-- > 0) {
3022                 Quad_t aquad;
3023                 fromstr = NEXTFROM;
3024                 aquad = (Quad_t)SvIV_no_inf(fromstr, datumtype);
3025                 PUSH_VAR(utf8, cur, aquad, needs_swap);
3026             }
3027             break;
3028 #endif
3029         case 'P':
3030             len = 1;            /* assume SV is correct length */
3031             GROWING(utf8, cat, start, cur, sizeof(char *));
3032             /* FALLTHROUGH */
3033         case 'p':
3034             while (len-- > 0) {
3035                 const char *aptr;
3036
3037                 fromstr = NEXTFROM;
3038                 SvGETMAGIC(fromstr);
3039                 if (!SvOK(fromstr)) aptr = NULL;
3040                 else {
3041                     /* XXX better yet, could spirit away the string to
3042                      * a safe spot and hang on to it until the result
3043                      * of pack() (and all copies of the result) are
3044                      * gone.
3045                      */
3046                     if (((SvTEMP(fromstr) && SvREFCNT(fromstr) == 1)
3047                          || (SvPADTMP(fromstr) &&
3048                              !SvREADONLY(fromstr)))) {
3049                         Perl_ck_warner(aTHX_ packWARN(WARN_PACK),
3050                                        "Attempt to pack pointer to temporary value");
3051                     }
3052                     if (SvPOK(fromstr) || SvNIOK(fromstr))
3053                         aptr = SvPV_nomg_const_nolen(fromstr);
3054                     else
3055                         aptr = SvPV_force_flags_nolen(fromstr, 0);
3056                 }
3057                 PUSH_VAR(utf8, cur, aptr, needs_swap);
3058             }
3059             break;
3060         case 'u': {
3061             const char *aptr, *aend;
3062             bool from_utf8;
3063
3064             fromstr = NEXTFROM;
3065             if (len <= 2) len = 45;
3066             else len = len / 3 * 3;
3067             if (len >= 64) {
3068                 Perl_ck_warner(aTHX_ packWARN(WARN_PACK),
3069                                "Field too wide in 'u' format in pack");
3070                 len = 63;
3071             }
3072             aptr = SvPV_const(fromstr, fromlen);
3073             from_utf8 = DO_UTF8(fromstr);
3074             if (from_utf8) {
3075                 aend = aptr + fromlen;
3076                 fromlen = sv_len_utf8_nomg(fromstr);
3077             } else aend = NULL; /* Unused, but keep compilers happy */
3078             GROWING(utf8, cat, start, cur, (fromlen+2) / 3 * 4 + (fromlen+len-1)/len * 2);
3079             while (fromlen > 0) {
3080                 U8 *end;
3081                 I32 todo;
3082                 U8 hunk[1+63/3*4+1];
3083
3084                 if ((I32)fromlen > len)
3085                     todo = len;
3086                 else
3087                     todo = fromlen;
3088                 if (from_utf8) {
3089                     char buffer[64];
3090                     if (!S_utf8_to_bytes(aTHX_ &aptr, aend, buffer, todo,
3091                                       'u' | TYPE_IS_PACK)) {
3092                         *cur = '\0';
3093                         SvCUR_set(cat, cur - start);
3094                         Perl_croak(aTHX_ "panic: string is shorter than advertised, "
3095                                    "aptr=%p, aend=%p, buffer=%p, todo=%ld",
3096                                    aptr, aend, buffer, (long) todo);
3097                     }
3098                     end = doencodes(hunk, (const U8 *)buffer, todo);
3099                 } else {
3100                     end = doencodes(hunk, (const U8 *)aptr, todo);
3101                     aptr += todo;
3102                 }
3103                 PUSH_BYTES(utf8, cur, hunk, end-hunk, 0);
3104                 fromlen -= todo;
3105             }
3106             break;
3107         }
3108         }
3109         *cur = '\0';
3110         SvCUR_set(cat, cur - start);
3111       no_change:
3112         *symptr = lookahead;
3113     }
3114     return beglist;
3115 }
3116 #undef NEXTFROM
3117
3118
3119 PP(pp_pack)
3120 {
3121     dSP; dMARK; dORIGMARK; dTARGET;
3122     SV *cat = TARG;
3123     STRLEN fromlen;
3124     SV *pat_sv = *++MARK;
3125     const char *pat = SvPV_const(pat_sv, fromlen);
3126     const char *patend = pat + fromlen;
3127
3128     MARK++;
3129     SvPVCLEAR(cat);
3130     SvUTF8_off(cat);
3131
3132     packlist(cat, pat, patend, MARK, SP + 1);
3133
3134     SvSETMAGIC(cat);
3135     SP = ORIGMARK;
3136     PUSHs(cat);
3137     RETURN;
3138 }
3139
3140 /*
3141  * ex: set ts=8 sts=4 sw=4 et:
3142  */