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