~ubuntu-branches/ubuntu/hoary/libextractor/hoary

« back to all changes in this revision

Viewing changes to src/plugins/zipextractor.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Baumann
  • Date: 2004-10-30 23:50:00 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20041030235000-poix4e5mzhmzkpbk
Tags: 0.3.10-2
* Added fix from cvs for various Sparc64 problems (Closes #278905).
* Added workaround from cvs for re-load glib problem of OLE2 extractor.
* debian/watch added.

Show diffs side-by-side

added added

removed removed

Lines of Context:
36
36
 
37
37
     No Copyright 2003 Julia Wolf
38
38
 
39
 
 **/
 
39
 */
40
40
 
41
41
/*
42
42
 * This file is part of libextractor.
58
58
 * Boston, MA 02111-1307, USA.
59
59
 */
60
60
 
61
 
 
 
61
#include "platform.h"
62
62
#include "extractor.h"
63
 
#include <string.h>
64
 
#include <stdio.h>
65
 
#include <sys/types.h>
66
 
#include <sys/stat.h>
67
 
#include <unistd.h>
68
 
#include <stdlib.h>
69
63
 
70
64
#define DEBUG_EXTRACT_ZIP 0
71
65
 
104
98
  /* I think the smallest zipfile you can have is about 120 bytes */
105
99
  if ( (NULL==data) || (size < 100) )
106
100
    return prev;  
107
 
  info = malloc(sizeof(zip_entry));
108
 
  info->next = NULL;
109
101
 
 
102
  if ( !( ('P'==data[0]) && ('K'==data[1]) && (0x03==data[2]) && (0x04==data[3])) )
 
103
    return prev;
 
104
  
110
105
  /* The filenames for each file in a zipfile are stored in two locations.
111
106
   * There is one at the start of each entry, just before the compressed data,
112
107
   * and another at the end in a 'central directory structure'.
143
138
   */
144
139
 
145
140
 
146
 
  // the signature can't be more than 22 bytes from the end
 
141
  /*  the signature can't be more than 22 bytes from the end */
147
142
  offset = size-22;
148
143
  pos = &data[offset];
149
144
 
155
150
     break out if we go more than 64K backwards and havn't found it, or if we hit the
156
151
     begining of the file. */
157
152
 
158
 
  while ( !( ('P'==pos[0]) && ('K'==pos[1]) && (0x05==pos[2]) && (0x06==pos[3])) ) {
159
 
    if (offset > stop ) 
160
 
      pos = &data[offset--];
161
 
    else 
162
 
      break;
163
 
  }
164
 
 
 
153
  while ( ( !( ('P'==pos[0]) && ('K'==pos[1]) && (0x05==pos[2]) && (0x06==pos[3])) ) &&
 
154
          (offset > stop) )
 
155
    pos = &data[offset--];
 
156
  
165
157
  if (offset==stop) {
166
158
#if DEBUG_EXTRACT_ZIP
167
159
    fprintf(stderr,
168
160
            "Did not find end of central directory structure signature. offset: %i\n",
169
161
            offset);
170
162
#endif
171
 
    free(info);
172
163
    return prev;
173
164
  }
174
165
 
177
168
  /* so slurp down filecomment while here... */
178
169
 
179
170
  filecomment_length = pos[20] + (pos[21]<<8);
180
 
  if (filecomment_length + offset + 22 >= size) {
181
 
    free(info);
 
171
  if (filecomment_length + offset + 22 > size) {
182
172
    return prev; /* invalid zip file format! */
183
173
  }
184
 
  filecomment = malloc(filecomment_length+1);
185
 
  memcpy(filecomment,
186
 
         &pos[22], 
187
 
         filecomment_length);
188
 
  filecomment[filecomment_length] = '\0';
 
174
  filecomment = NULL;
 
175
  if (filecomment_length > 0) {
 
176
    filecomment = malloc(filecomment_length+1);
 
177
    memcpy(filecomment,
 
178
           &pos[22], 
 
179
           filecomment_length);
 
180
    filecomment[filecomment_length] = '\0';
 
181
  }
189
182
 
190
183
 
191
184
  if ( (0!=pos[4])&&(0!=pos[5]) ) {
213
206
  /* stop   = pos[12] + (pos[13]<<8) + (pos[14]<<16) + (pos[15]<<24); */ /* length of central dir */
214
207
  if (offset + 46 > size) {
215
208
    /* not a zip */
216
 
    free(info);
217
 
    free(filecomment);
 
209
    if (filecomment != NULL)
 
210
      free(filecomment);
218
211
    return prev;    
219
212
  }
220
213
  pos = &data[offset]; /* jump */
252
245
            "Did not find central directory structure signature. offset: %i\n",
253
246
            offset);
254
247
#endif
255
 
    free(filecomment);
256
 
    free(info);
 
248
    if (filecomment != NULL)
 
249
      free(filecomment);
257
250
    return prev;
258
251
  }
259
252
 
260
 
  start = info;
 
253
  start = NULL;
 
254
  info = NULL;
261
255
  do {   /* while ( (0x01==pos[2])&&(0x02==pos[3]) ) */
262
 
 
263
 
    /* The NULL test is only needed for the first pass through the while loop */
264
 
    /* I think there's a better way to do this */
265
 
    if (NULL!=info->next) {
266
 
       info = info->next;
267
 
    }
268
 
 
269
 
    entry_count++; // check to make sure we found everything at the end
 
256
    entry_count++; /* check to make sure we found everything at the end */
270
257
 
271
258
    name_length     = pos[28] + (pos[29]<<8);
272
259
    extra_length    = pos[30] + (pos[31]<<8);
285
272
#endif
286
273
 
287
274
    /* yay, finally get filenames */
288
 
    info->next     = malloc(sizeof(info));
 
275
    if (start == NULL) {
 
276
      start = malloc(sizeof(zip_entry));
 
277
      start->next = NULL;
 
278
      info = start;
 
279
    } else {
 
280
      info->next = malloc(sizeof(zip_entry));
 
281
      info = info->next;
 
282
      info->next = NULL;
 
283
    }
289
284
    info->filename = malloc(name_length + 1);
290
285
    info->comment  = malloc(comment_length + 1);
291
286
 
323
318
        free(info);     
324
319
        info = start;
325
320
      }
326
 
      free(filecomment);
 
321
      if (filecomment != NULL)
 
322
        free(filecomment);
327
323
      return prev;
328
324
    }
329
325
 
330
326
  } while ( (0x01==pos[2])&&(0x02==pos[3]) );
331
327
 
332
328
  /* end list */
333
 
  info->next = NULL;
 
329
 
334
330
 
335
331
  /* TODO: should this return an error? indicates corrupt zipfile (or
336
332
     disk missing in middle of multi-disk)? */
349
345
  keyword->keywordType = EXTRACTOR_MIMETYPE;
350
346
  prev = keyword;   
351
347
 
352
 
  if (strlen(filecomment)) {
 
348
  if (filecomment != NULL) {
353
349
    EXTRACTOR_KeywordList * kw
354
350
      = malloc(sizeof(EXTRACTOR_KeywordList));
355
351
    kw->next = prev;    
362
358
  /* if we've gotten to here then there is at least one zip entry (see get_zipinfo call above) */
363
359
  /* note: this free()'s the info list as it goes */
364
360
  info = start;
365
 
  while (NULL!=info) {
 
361
  while (NULL != info) {
366
362
    if (strlen(info->filename)){
367
363
      EXTRACTOR_KeywordList * keyword = malloc(sizeof(EXTRACTOR_KeywordList));
368
364
      keyword->next = prev;    
369
365
      keyword->keyword = strdup(info->filename);
370
366
      keyword->keywordType = EXTRACTOR_FILENAME;
371
367
      prev = keyword;
 
368
    }  
 
369
    if (info->filename != NULL)
372
370
      free(info->filename);
373
 
    }  
 
371
 
374
372
    if (strlen(info->comment)){
375
373
      EXTRACTOR_KeywordList * keyword = malloc(sizeof(EXTRACTOR_KeywordList));    
376
374
      keyword->next = prev;
377
375
      keyword->keyword = strdup(info->comment);
378
376
      keyword->keywordType = EXTRACTOR_COMMENT;
379
377
      prev = keyword;
 
378
    }
 
379
    if (info->comment != NULL)
380
380
      free(info->comment);
381
 
    }
382
381
    tmp = info;
383
382
    info = info->next;
384
383
    free(tmp);