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