8868c7db338918a36d53bccb0354480c3997c64a
[pspp] / src / libpspp / zip-reader.c
1 /* PSPP - a program for statistical analysis.
2    Copyright (C) 2011, 2013, 2014 Free Software Foundation, Inc.
3
4    This program is free software: you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation, either version 3 of the License, or
7    (at your option) any later version.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program.  If not, see <http://www.gnu.org/licenses/>. */
16
17 #include <config.h>
18
19 #include <inttypes.h>
20 #include <stdbool.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24
25 #include <errno.h>
26 #include <xalloc.h>
27 #include <libpspp/assertion.h>
28 #include <libpspp/compiler.h>
29
30 #include "str.h"
31
32 #include "integer-format.h"
33 #include "zip-reader.h"
34 #include "zip-private.h"
35
36 #include "gettext.h"
37 #define _(msgid) gettext (msgid)
38 #define N_(msgid) (msgid)
39
40 struct zip_member
41 {
42   char *file_name;             /* File name. */
43   char *member_name;          /* Member name. */
44   FILE *fp;                   /* The stream from which the data is read */
45   uint32_t offset;            /* Starting offset in file. */
46   uint32_t comp_size;         /* Length of member file data, in bytes. */
47   uint32_t ucomp_size;        /* Uncompressed length of member file data, in bytes. */
48   const struct decompressor *decompressor;
49
50   size_t bytes_unread;       /* Number of bytes left in the member available for reading */
51   struct string *errmsgs;    /* A string to hold error messages.
52                                 This string is NOT owned by this object. */
53   void *aux;
54 };
55
56 struct decompressor
57 {
58   bool (*init) (struct zip_member *);
59   int  (*read) (struct zip_member *, void *, size_t);
60   void (*finish) (struct zip_member *);
61 };
62 static const struct decompressor stored_decompressor;
63 static const struct decompressor inflate_decompressor;
64
65 static bool find_eocd (FILE *fp, off_t *off);
66
67 static const struct decompressor *
68 get_decompressor (uint16_t c)
69 {
70   switch (c)
71     {
72     case 0:
73       return &stored_decompressor;
74
75     case 8:
76       return &inflate_decompressor;
77
78     default:
79       return NULL;
80     }
81 }
82
83 struct zip_reader
84 {
85   char *file_name;                  /* The name of the file from which the data is read */
86   uint16_t n_entries;              /* Number of directory entries. */
87   struct zip_entry *entries;       /* Directory entries. */
88   struct string *errs;             /* A string to hold error messages.  This
89                                       string is NOT owned by this object. */
90 };
91
92 struct zip_entry
93 {
94   uint32_t offset;            /* Starting offset in file. */
95   uint32_t comp_size;         /* Length of member file data, in bytes. */
96   uint32_t ucomp_size;        /* Uncompressed length of member file data, in bytes. */
97   char *name;                 /* Name of member file. */
98 };
99
100 void
101 zip_member_finish (struct zip_member *zm)
102 {
103   if (zm)
104     {
105       free (zm->file_name);
106       free (zm->member_name);
107       ds_clear (zm->errmsgs);
108       zm->decompressor->finish (zm);
109       fclose (zm->fp);
110       free (zm);
111     }
112 }
113
114 /* Destroy the zip reader */
115 void
116 zip_reader_destroy (struct zip_reader *zr)
117 {
118   int i;
119   if (zr == NULL)
120     return;
121
122   free (zr->file_name);
123
124   for (i = 0; i < zr->n_entries; ++i)
125     {
126       struct zip_entry *ze = &zr->entries[i];
127       free (ze->name);
128     }
129   free (zr->entries);
130   free (zr);
131 }
132
133
134 /* Skip N bytes in F */
135 static void
136 skip_bytes (FILE *f, size_t n)
137 {
138   fseeko (f, n, SEEK_CUR);
139 }
140
141 static bool get_bytes (FILE *f, void *x, size_t n) WARN_UNUSED_RESULT;
142
143
144 /* Read N bytes from F, storing the result in X */
145 static bool
146 get_bytes (FILE *f, void *x, size_t n)
147 {
148   return (n == fread (x, 1, n, f));
149 }
150
151 /* Read a 32 bit value from F */
152 static bool WARN_UNUSED_RESULT
153 get_u32 (FILE *f, uint32_t *v)
154 {
155   uint32_t x;
156   if (!get_bytes (f, &x, sizeof x))
157     return false;
158   *v = le_to_native32 (x);
159   return true;
160 }
161
162 /* Read a 16 bit value from F */
163 static bool WARN_UNUSED_RESULT
164 get_u16 (FILE *f, uint16_t *v)
165 {
166   uint16_t x;
167   if (!get_bytes (f, &x, sizeof x))
168     return false;
169   *v = le_to_native16 (x);
170   return true;
171 }
172
173
174 /* Read 32 bit integer and compare it with EXPECTED.
175    place an error string in ERR if necessary. */
176 static bool
177 check_magic (FILE *f, const char *file_name,
178              uint32_t expected, struct string *err)
179 {
180   uint32_t magic;
181
182   if (! get_u32 (f, &magic)) return false;
183
184   if ((expected != magic))
185     {
186       ds_put_format (err,
187                      _("%s: corrupt archive at 0x%llx: "
188                        "expected %#"PRIx32" but got %#"PRIx32),
189                      file_name,
190                      (long long int) ftello (f) - sizeof (uint32_t),
191                      expected, magic);
192
193       return false;
194     }
195   return true;
196 }
197
198
199 /* Reads upto BYTES bytes from ZM and puts them in BUF.
200    Returns the number of bytes read, or -1 on error */
201 int
202 zip_member_read (struct zip_member *zm, void *buf, size_t bytes)
203 {
204   int bytes_read = 0;
205
206   ds_clear (zm->errmsgs);
207
208   if (bytes > zm->bytes_unread)
209     bytes = zm->bytes_unread;
210
211   bytes_read  = zm->decompressor->read (zm, buf, bytes);
212   if (bytes_read < 0)
213     return bytes_read;
214
215   zm->bytes_unread -= bytes_read;
216
217   return bytes_read;
218 }
219
220 /* Read all of ZM into memory, storing the data in *DATAP and its size in *NP.
221    Returns NULL if successful, otherwise an error string that the caller
222    must eventually free(). */
223 char * WARN_UNUSED_RESULT
224 zip_member_read_all (struct zip_reader *zr, const char *member_name,
225                      void **datap, size_t *np)
226 {
227   struct zip_member *zm = zip_member_open (zr, member_name);
228   if (!zm)
229     {
230       *datap = NULL;
231       *np = 0;
232       return ds_steal_cstr (zr->errs);
233     }
234
235   *datap = xmalloc (zm->ucomp_size);
236   *np = zm->ucomp_size;
237
238   uint8_t *data = *datap;
239   while (zm->bytes_unread)
240     if (zip_member_read (zm, data + (zm->ucomp_size - zm->bytes_unread),
241                          zm->bytes_unread) == -1)
242       {
243         zip_member_finish (zm);
244         free (*datap);
245         *datap = NULL;
246         *np = 0;
247         return ds_steal_cstr (zr->errs);
248       }
249
250   zip_member_finish (zm);
251   return NULL;
252 }
253
254 /* Read a central directory header from FILE and initializes ZE with it.
255    Returns true if successful, false otherwise.  On error, appends error
256    messages to ERRS. */
257 static bool
258 zip_header_read_next (FILE *file, const char *file_name,
259                       struct zip_entry *ze, struct string *errs)
260 {
261   uint16_t v, nlen, extralen;
262   uint16_t gp, time, date;
263   uint32_t expected_crc;
264
265   uint16_t clen, diskstart, iattr;
266   uint32_t eattr;
267   uint16_t comp_type;
268
269   if (! check_magic (file, file_name, MAGIC_SOCD, errs))
270     return false;
271
272   if (! get_u16 (file, &v)) return false;
273   if (! get_u16 (file, &v)) return false;
274   if (! get_u16 (file, &gp)) return false;
275   if (! get_u16 (file, &comp_type)) return false;
276   if (! get_u16 (file, &time)) return false;
277   if (! get_u16 (file, &date)) return false;
278   if (! get_u32 (file, &expected_crc)) return false;
279   if (! get_u32 (file, &ze->comp_size)) return false;
280   if (! get_u32 (file, &ze->ucomp_size)) return false;
281   if (! get_u16 (file, &nlen)) return false;
282   if (! get_u16 (file, &extralen)) return false;
283   if (! get_u16 (file, &clen)) return false;
284   if (! get_u16 (file, &diskstart)) return false;
285   if (! get_u16 (file, &iattr)) return false;
286   if (! get_u32 (file, &eattr)) return false;
287   if (! get_u32 (file, &ze->offset)) return false;
288
289   ze->name = xzalloc (nlen + 1);
290   if (! get_bytes (file, ze->name, nlen)) return false;
291
292   skip_bytes (file, extralen);
293
294   return true;
295 }
296
297
298 /* Create a reader from the zip called FILE_NAME */
299 struct zip_reader *
300 zip_reader_create (const char *file_name, struct string *errs)
301 {
302   uint16_t disknum, n_members, total_members;
303   off_t offset = 0;
304   uint32_t central_dir_start, central_dir_length;
305
306   struct zip_reader *zr = xzalloc (sizeof *zr);
307   zr->errs = errs;
308   if (zr->errs)
309     ds_init_empty (zr->errs);
310
311   FILE *file = fopen (file_name, "rb");
312   if (!file)
313     {
314       ds_put_format (zr->errs, _("%s: open failed (%s)"),
315                      file_name, strerror (errno));
316       free (zr);
317       return NULL;
318     }
319
320   if (! check_magic (file, file_name, MAGIC_LHDR, zr->errs))
321     {
322       fclose (file);
323       free (zr);
324       return NULL;
325     }
326
327   if (! find_eocd (file, &offset))
328     {
329       ds_put_format (zr->errs, _("%s: cannot find central directory"),
330                      file_name);
331       fclose (file);
332       free (zr);
333       return NULL;
334     }
335
336   if (0 != fseeko (file, offset, SEEK_SET))
337     {
338       ds_put_format (zr->errs, _("%s: seek failed (%s)"),
339                      file_name, strerror (errno));
340       fclose (file);
341       free (zr);
342       return NULL;
343     }
344
345
346   if (! check_magic (file, file_name, MAGIC_EOCD, zr->errs))
347     {
348       fclose (file);
349       free (zr);
350       return NULL;
351     }
352
353   if (! get_u16 (file, &disknum)
354       || ! get_u16 (file, &disknum)
355
356       || ! get_u16 (file, &n_members)
357       || ! get_u16 (file, &total_members)
358
359       || ! get_u32 (file, &central_dir_length)
360       || ! get_u32 (file, &central_dir_start))
361     {
362       fclose (file);
363       free (zr);
364       return NULL;
365     }
366
367   if (0 != fseeko (file, central_dir_start, SEEK_SET))
368     {
369       ds_put_format (zr->errs, _("%s: seek failed (%s)"),
370                      file_name, strerror (errno));
371       fclose (file);
372       free (zr);
373       return NULL;
374     }
375
376   zr->file_name = xstrdup (file_name);
377
378   zr->entries = xcalloc (n_members, sizeof *zr->entries);
379   for (int i = 0; i < n_members; i++)
380     {
381       if (!zip_header_read_next (file, file_name,
382                                  &zr->entries[zr->n_entries], errs))
383         {
384           fclose (file);
385           zip_reader_destroy (zr);
386           return NULL;
387         }
388       zr->n_entries++;
389     }
390
391   fclose (file);
392   return zr;
393 }
394
395 static struct zip_entry *
396 zip_entry_find (const struct zip_reader *zr, const char *member)
397 {
398   for (int i = 0; i < zr->n_entries; ++i)
399     {
400       struct zip_entry *ze = &zr->entries[i];
401       if (0 == strcmp (ze->name, member))
402         return ze;
403     }
404   return NULL;
405 }
406
407 const char *
408 zip_reader_get_member_name(const struct zip_reader *zr, size_t idx)
409 {
410   return idx < zr->n_entries ? zr->entries[idx].name : NULL;
411 }
412
413 /* Returns true if ZR contains a member named MEMBER, false otherwise. */
414 bool
415 zip_reader_contains_member (const struct zip_reader *zr, const char *member)
416 {
417   return zip_entry_find (zr, member) != NULL;
418 }
419
420 /* Return the member called MEMBER from the reader ZR  */
421 struct zip_member *
422 zip_member_open (struct zip_reader *zr, const char *member)
423 {
424   struct zip_entry *ze = zip_entry_find (zr, member);
425   if (ze == NULL)
426     {
427       ds_put_format (zr->errs, _("%s: unknown member \"%s\""),
428                      zr->file_name, member);
429       return NULL;
430     }
431
432   FILE *fp = fopen (zr->file_name, "rb");
433   if (!fp)
434     {
435       ds_put_format (zr->errs, _("%s: open failed (%s)"),
436                      zr->file_name, strerror (errno));
437       return NULL;
438     }
439
440   struct zip_member *zm = xmalloc (sizeof *zm);
441   zm->file_name = xstrdup (zr->file_name);
442   zm->member_name = xstrdup (member);
443   zm->fp = fp;
444   zm->offset = ze->offset;
445   zm->comp_size = ze->comp_size;
446   zm->ucomp_size = ze->ucomp_size;
447   zm->decompressor = NULL;
448   zm->bytes_unread = ze->ucomp_size;
449   zm->errmsgs = zr->errs;
450   zm->aux = NULL;
451
452   if (0 != fseeko (zm->fp, zm->offset, SEEK_SET))
453     {
454       ds_put_format (zr->errs, _("%s: seek failed (%s)"),
455                      ze->name, strerror (errno));
456       goto error;
457     }
458
459   if (! check_magic (zm->fp, zr->file_name, MAGIC_LHDR, zr->errs))
460     goto error;
461
462   uint16_t v, nlen, extra_len;
463   uint16_t gp, comp_type, time, date;
464   uint32_t ucomp_size, comp_size;
465   uint32_t crc;
466   if (! get_u16 (zm->fp, &v)) goto error;
467   if (! get_u16 (zm->fp, &gp)) goto error;
468   if (! get_u16 (zm->fp, &comp_type)) goto error;
469   zm->decompressor = get_decompressor (comp_type);
470   if (! zm->decompressor) goto error;
471   if (! get_u16 (zm->fp, &time)) goto error;
472   if (! get_u16 (zm->fp, &date)) goto error;
473   if (! get_u32 (zm->fp, &crc)) goto error;
474   if (! get_u32 (zm->fp, &comp_size)) goto error;
475
476   if (! get_u32 (zm->fp, &ucomp_size)) goto error;
477   if (! get_u16 (zm->fp, &nlen)) goto error;
478   if (! get_u16 (zm->fp, &extra_len)) goto error;
479
480   char *name = xzalloc (nlen + 1);
481   if (! get_bytes (zm->fp, name, nlen))
482     {
483       free (name);
484       goto error;
485     }
486   if (strcmp (name, ze->name) != 0)
487     {
488       ds_put_format (zm->errmsgs,
489                      _("%s: name mismatch between central directory (%s) "
490                        "and local file header (%s)"),
491                      zm->file_name, ze->name, name);
492       free (name);
493       goto error;
494     }
495   free (name);
496
497   skip_bytes (zm->fp, extra_len);
498
499   if (!zm->decompressor->init (zm))
500     goto error;
501
502   return zm;
503
504 error:
505   fclose (zm->fp);
506   free (zm->file_name);
507   free (zm->member_name);
508   free (zm);
509   return NULL;
510 }
511
512 \f
513
514 static bool probe_magic (FILE *fp, uint32_t magic, off_t start, off_t stop, off_t *off);
515
516
517 /* Search for something that looks like the End Of Central Directory in FP.
518    If found, the offset of the record will be placed in OFF.
519    Returns true if found false otherwise.
520 */
521 static bool
522 find_eocd (FILE *fp, off_t *off)
523 {
524   off_t start, stop;
525   const uint32_t magic = MAGIC_EOCD;
526   bool found = false;
527
528   /* The magic cannot be more than 22 bytes from the end of the file,
529      because that is the minimum length of the EndOfCentralDirectory
530      record.
531    */
532   if (0 > fseeko (fp, -22, SEEK_END))
533     {
534       return false;
535     }
536   start = ftello (fp);
537   stop = start + sizeof (magic);
538   do
539     {
540       found = probe_magic (fp, magic, start, stop, off);
541       /* FIXME: For extra confidence lookup the directory start record here*/
542       if (start == 0)
543         break;
544       stop = start + sizeof (magic);
545       start >>= 1;
546     }
547   while (!found);
548
549   return found;
550 }
551
552
553 /*
554   Search FP for MAGIC starting at START and reaching until STOP.
555   Returns true iff MAGIC is found.  False otherwise.
556   OFF receives the location of the magic.
557 */
558 static bool
559 probe_magic (FILE *fp, uint32_t magic, off_t start, off_t stop, off_t *off)
560 {
561   int i;
562   int state = 0;
563   unsigned char seq[4];
564   unsigned char byte;
565
566   if (0 > fseeko (fp, start, SEEK_SET))
567     {
568       return -1;
569     }
570
571   for (i = 0; i < 4 ; ++i)
572     {
573       seq[i] = (magic >> i * 8) & 0xFF;
574     }
575
576   do
577     {
578       if (1 != fread (&byte, 1, 1, fp))
579         break;
580
581       if (byte == seq[state])
582         state++;
583       else
584         state = 0;
585
586       if (state == 4)
587         {
588           *off = ftello (fp) - 4;
589           return true;
590         }
591       start++;
592       if (start >= stop)
593         break;
594     }
595   while (!feof (fp));
596
597   return false;
598 }
599 \f
600 /* Null decompressor. */
601
602 static int
603 stored_read (struct zip_member *zm, void *buf, size_t n)
604 {
605   return fread (buf, 1, n, zm->fp);
606 }
607
608 static bool
609 stored_init (struct zip_member *zm UNUSED)
610 {
611   return true;
612 }
613
614 static void
615 stored_finish (struct zip_member *zm UNUSED)
616 {
617   /* Nothing required */
618 }
619
620 static const struct decompressor stored_decompressor =
621   {stored_init, stored_read, stored_finish};
622 \f
623 /* Inflate decompressor. */
624
625 #undef crc32
626 #include <zlib.h>
627
628 #define UCOMPSIZE 4096
629
630 struct inflator
631 {
632   z_stream zss;
633   int state;
634   unsigned char ucomp[UCOMPSIZE];
635   size_t bytes_uncomp;
636   size_t ucomp_bytes_read;
637
638   /* Two bitfields as defined by RFC1950 */
639   uint16_t cmf_flg ;
640 };
641
642 static void
643 inflate_finish (struct zip_member *zm)
644 {
645   struct inflator *inf = zm->aux;
646
647   inflateEnd (&inf->zss);
648
649   free (inf);
650 }
651
652 static bool
653 inflate_init (struct zip_member *zm)
654 {
655   int r;
656   struct inflator *inf = xzalloc (sizeof *inf);
657
658   uint16_t flg = 0 ;
659   uint16_t cmf = 0x8; /* Always 8 for inflate */
660
661   const uint16_t cinfo = 7;  /* log_2(Window size) - 8 */
662
663   cmf |= cinfo << 4;     /* Put cinfo into the high nibble */
664
665   /* make these into a 16 bit word */
666   inf->cmf_flg = (cmf << 8) | flg;
667
668   /* Set the check bits */
669   inf->cmf_flg += 31 - (inf->cmf_flg % 31);
670   assert (inf->cmf_flg % 31 == 0);
671
672   inf->zss.next_in = Z_NULL;
673   inf->zss.avail_in = 0;
674   inf->zss.zalloc = Z_NULL;
675   inf->zss.zfree  = Z_NULL;
676   inf->zss.opaque = Z_NULL;
677   r = inflateInit (&inf->zss);
678
679   if (Z_OK != r)
680     {
681       ds_put_format (zm->errmsgs,
682                      _("%s: cannot initialize inflator (%s)"),
683                      zm->file_name, zError (r));
684       return false;
685     }
686
687   zm->aux = inf;
688
689   return true;
690 }
691
692 static int
693 inflate_read (struct zip_member *zm, void *buf, size_t n)
694 {
695   int r;
696   struct inflator *inf = zm->aux;
697
698   if (inf->zss.avail_in == 0)
699     {
700       int bytes_read;
701       int bytes_to_read;
702       int pad = 0;
703
704       if (inf->state == 0)
705         {
706           inf->ucomp[1] = inf->cmf_flg ;
707           inf->ucomp[0] = inf->cmf_flg >> 8 ;
708
709           pad = 2;
710           inf->state++;
711         }
712
713       bytes_to_read = zm->comp_size - inf->ucomp_bytes_read;
714
715       if (bytes_to_read == 0)
716         return 0;
717
718       if (bytes_to_read > UCOMPSIZE)
719         bytes_to_read = UCOMPSIZE;
720
721       bytes_read = fread (inf->ucomp + pad, 1, bytes_to_read - pad, zm->fp);
722
723       inf->ucomp_bytes_read += bytes_read;
724
725       inf->zss.avail_in = bytes_read + pad;
726       inf->zss.next_in = inf->ucomp;
727     }
728   inf->zss.avail_out = n;
729   inf->zss.next_out = buf;
730
731   r = inflate (&inf->zss, Z_NO_FLUSH);
732   if (Z_OK == r)
733     {
734       return n - inf->zss.avail_out;
735     }
736
737   ds_put_format (zm->errmsgs, _("%s: error inflating \"%s\" (%s)"),
738                  zm->file_name, zm->member_name, zError (r));
739
740   return -1;
741 }
742
743 static const struct decompressor inflate_decompressor =
744   {inflate_init, inflate_read, inflate_finish};
745