aboutsummaryrefslogtreecommitdiff
path: root/src/plugins/deb_extractor.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/deb_extractor.c')
-rw-r--r--src/plugins/deb_extractor.c284
1 files changed, 143 insertions, 141 deletions
diff --git a/src/plugins/deb_extractor.c b/src/plugins/deb_extractor.c
index 2eb0028..16c6285 100644
--- a/src/plugins/deb_extractor.c
+++ b/src/plugins/deb_extractor.c
@@ -122,8 +122,8 @@ static struct Matches tmap[] = {
122static int 122static int
123processControl (const char *data, 123processControl (const char *data,
124 const size_t size, 124 const size_t size,
125 EXTRACTOR_MetaDataProcessor proc, 125 EXTRACTOR_MetaDataProcessor proc,
126 void *proc_cls) 126 void *proc_cls)
127{ 127{
128 size_t pos; 128 size_t pos;
129 char *key; 129 char *key;
@@ -134,49 +134,49 @@ processControl (const char *data,
134 134
135 pos = 0; 135 pos = 0;
136 while (pos < size) 136 while (pos < size)
137 { 137 {
138 for (colon = pos; ':' != data[colon]; colon++) 138 for (colon = pos; ':' != data[colon]; colon++)
139 if ((colon > size) || ('\n' == data[colon])) 139 if ((colon > size) || ('\n' == data[colon]))
140 return 0; 140 return 0;
141 colon++;
142 while ((colon < size) && (isspace ((unsigned char) data[colon])))
141 colon++; 143 colon++;
142 while ((colon < size) && (isspace ((unsigned char) data[colon]))) 144 eol = colon;
143 colon++; 145 while ((eol < size) &&
144 eol = colon; 146 (('\n' != data[eol]) ||
145 while ((eol < size) && 147 ((eol + 1 < size) && (' ' == data[eol + 1]))))
146 (('\n' != data[eol]) || 148 eol++;
147 ((eol + 1 < size) && (' ' == data[eol + 1])))) 149 if ((eol == colon) || (eol > size))
148 eol++; 150 return 0;
149 if ((eol == colon) || (eol > size)) 151 if (NULL == (key = stndup (&data[pos], colon - pos)))
152 return 0;
153 for (i = 0; NULL != tmap[i].text; i++)
154 {
155 if (0 != strcmp (key, tmap[i].text))
156 continue;
157 if (NULL == (val = stndup (&data[colon], eol - colon)))
158 {
159 free (key);
150 return 0; 160 return 0;
151 if (NULL == (key = stndup (&data[pos], colon - pos))) 161 }
152 return 0; 162 if (0 != proc (proc_cls,
153 for (i = 0; NULL != tmap[i].text; i++) 163 "deb",
154 { 164 tmap[i].type,
155 if (0 != strcmp (key, tmap[i].text)) 165 EXTRACTOR_METAFORMAT_UTF8,
156 continue; 166 "text/plain",
157 if (NULL == (val = stndup (&data[colon], eol - colon))) 167 val,
158 { 168 strlen (val) + 1))
159 free (key); 169 {
160 return 0; 170 free (val);
161 } 171 free (key);
162 if (0 != proc (proc_cls, 172 return 1;
163 "deb", 173 }
164 tmap[i].type, 174 free (val);
165 EXTRACTOR_METAFORMAT_UTF8, 175 break;
166 "text/plain",
167 val,
168 strlen(val) + 1))
169 {
170 free (val);
171 free (key);
172 return 1;
173 }
174 free (val);
175 break;
176 }
177 free (key);
178 pos = eol + 1;
179 } 176 }
177 free (key);
178 pos = eol + 1;
179 }
180 return 0; 180 return 0;
181} 181}
182 182
@@ -291,9 +291,9 @@ struct USTarHeader
291 */ 291 */
292static int 292static int
293processControlTar (const char *data, 293processControlTar (const char *data,
294 size_t size, 294 size_t size,
295 EXTRACTOR_MetaDataProcessor proc, 295 EXTRACTOR_MetaDataProcessor proc,
296 void *proc_cls) 296 void *proc_cls)
297{ 297{
298 struct TarHeader *tar; 298 struct TarHeader *tar;
299 struct USTarHeader *ustar; 299 struct USTarHeader *ustar;
@@ -301,42 +301,42 @@ processControlTar (const char *data,
301 301
302 pos = 0; 302 pos = 0;
303 while (pos + sizeof (struct TarHeader) < size) 303 while (pos + sizeof (struct TarHeader) < size)
304 {
305 unsigned long long fsize;
306 char buf[13];
307
308 tar = (struct TarHeader *) &data[pos];
309 if (pos + sizeof (struct USTarHeader) < size)
304 { 310 {
305 unsigned long long fsize; 311 ustar = (struct USTarHeader *) &data[pos];
306 char buf[13]; 312 if (0 == strncmp ("ustar", &ustar->magic[0], strlen ("ustar")))
307 313 pos += 512; /* sizeof (struct USTarHeader); */
308 tar = (struct TarHeader *) & data[pos];
309 if (pos + sizeof (struct USTarHeader) < size)
310 {
311 ustar = (struct USTarHeader *) & data[pos];
312 if (0 == strncmp ("ustar", &ustar->magic[0], strlen ("ustar")))
313 pos += 512; /* sizeof (struct USTarHeader); */
314 else
315 pos += 257; /* sizeof (struct TarHeader); minus gcc alignment... */
316 }
317 else 314 else
318 { 315 pos += 257; /* sizeof (struct TarHeader); minus gcc alignment... */
319 pos += 257; /* sizeof (struct TarHeader); minus gcc alignment... */ 316 }
320 } 317 else
318 {
319 pos += 257; /* sizeof (struct TarHeader); minus gcc alignment... */
320 }
321 321
322 memcpy (buf, &tar->filesize[0], 12); 322 memcpy (buf, &tar->filesize[0], 12);
323 buf[12] = '\0'; 323 buf[12] = '\0';
324 if (1 != sscanf (buf, "%12llo", &fsize)) /* octal! Yuck yuck! */ 324 if (1 != sscanf (buf, "%12llo", &fsize)) /* octal! Yuck yuck! */
325 return 0; 325 return 0;
326 if ((pos + fsize > size) || (fsize > size) || (pos + fsize < pos)) 326 if ((pos + fsize > size) || (fsize > size) || (pos + fsize < pos))
327 return 0; 327 return 0;
328 328
329 if (0 == strncmp (&tar->name[0], "./control", strlen ("./control"))) 329 if (0 == strncmp (&tar->name[0], "./control", strlen ("./control")))
330 { 330 {
331 /* found the 'control' file we were looking for */ 331 /* found the 'control' file we were looking for */
332 return processControl (&data[pos], fsize, proc, proc_cls); 332 return processControl (&data[pos], fsize, proc, proc_cls);
333 }
334 if (0 != (fsize & 511))
335 fsize = (fsize | 511) + 1; /* round up! */
336 if (pos + fsize < pos)
337 return 0;
338 pos += fsize;
339 } 333 }
334 if (0 != (fsize & 511))
335 fsize = (fsize | 511) + 1; /* round up! */
336 if (pos + fsize < pos)
337 return 0;
338 pos += fsize;
339 }
340 return 0; 340 return 0;
341} 341}
342 342
@@ -371,42 +371,43 @@ processControlTGZ (struct EXTRACTOR_ExtractContext *ec,
371 return 0; 371 return 0;
372 off = 0; 372 off = 0;
373 while (off < size) 373 while (off < size)
374 { 374 {
375 if (0 >= (sret = ec->read (ec->cls, &data, size - off))) 375 if (0 >= (sret = ec->read (ec->cls, &data, size - off)))
376 {
377 free (cdata);
378 return 0;
379 }
380 memcpy (&cdata[off],
381 data,
382 sret);
383 off += sret;
384 }
385 bufSize = cdata[size - 4] + (cdata[size - 3] << 8) + (cdata[size - 2] << 16) + (cdata[size - 1] << 24);
386 if (bufSize > MAX_CONTROL_SIZE)
387 { 376 {
388 free (cdata); 377 free (cdata);
389 return 0; 378 return 0;
390 } 379 }
380 memcpy (&cdata[off],
381 data,
382 sret);
383 off += sret;
384 }
385 bufSize = cdata[size - 4] + (cdata[size - 3] << 8) + (cdata[size - 2] << 16)
386 + (cdata[size - 1] << 24);
387 if (bufSize > MAX_CONTROL_SIZE)
388 {
389 free (cdata);
390 return 0;
391 }
391 if (NULL == (buf = malloc (bufSize))) 392 if (NULL == (buf = malloc (bufSize)))
392 { 393 {
393 free (cdata); 394 free (cdata);
394 return 0; 395 return 0;
395 } 396 }
396 ret = 0; 397 ret = 0;
397 memset (&strm, 0, sizeof (z_stream)); 398 memset (&strm, 0, sizeof (z_stream));
398 strm.next_in = (Bytef *) data; 399 strm.next_in = (Bytef *) data;
399 strm.avail_in = size; 400 strm.avail_in = size;
400 if (Z_OK == inflateInit2 (&strm, 15 + 32)) 401 if (Z_OK == inflateInit2 (&strm, 15 + 32))
401 { 402 {
402 strm.next_out = (Bytef *) buf; 403 strm.next_out = (Bytef *) buf;
403 strm.avail_out = bufSize; 404 strm.avail_out = bufSize;
404 inflate (&strm, Z_FINISH); 405 inflate (&strm, Z_FINISH);
405 if (strm.total_out > 0) 406 if (strm.total_out > 0)
406 ret = processControlTar (buf, strm.total_out, 407 ret = processControlTar (buf, strm.total_out,
407 ec->proc, ec->cls); 408 ec->proc, ec->cls);
408 inflateEnd (&strm); 409 inflateEnd (&strm);
409 } 410 }
410 free (buf); 411 free (buf);
411 free (cdata); 412 free (cdata);
412 return ret; 413 return ret;
@@ -481,49 +482,50 @@ EXTRACTOR_deb_extract_method (struct EXTRACTOR_ExtractContext *ec)
481 return; 482 return;
482 pos = 8; 483 pos = 8;
483 while (pos + sizeof (struct ObjectHeader) < fsize) 484 while (pos + sizeof (struct ObjectHeader) < fsize)
485 {
486 if (pos !=
487 ec->seek (ec->cls, pos, SEEK_SET))
488 return;
489 if (sizeof (struct ObjectHeader) !=
490 ec->read (ec->cls, &data, sizeof (struct ObjectHeader)))
491 return;
492 hdr = data;
493 if (0 != strncmp (&hdr->trailer[0], "`\n", 2))
494 return;
495 memcpy (buf, &hdr->filesize[0], 10);
496 buf[10] = '\0';
497 if (1 != sscanf (buf, "%10llu", &csize))
498 return;
499 pos += sizeof (struct ObjectHeader);
500 if ((pos + csize > fsize) || (csize > fsize) || (pos + csize < pos))
501 return;
502 if (0 == strncmp (&hdr->name[0],
503 "control.tar.gz",
504 strlen ("control.tar.gz")))
484 { 505 {
485 if (pos != 506 if (0 != processControlTGZ (ec,
486 ec->seek (ec->cls, pos, SEEK_SET)) 507 csize))
487 return;
488 if (sizeof (struct ObjectHeader) !=
489 ec->read (ec->cls, &data, sizeof (struct ObjectHeader)))
490 return;
491 hdr = data;
492 if (0 != strncmp (&hdr->trailer[0], "`\n", 2))
493 return; 508 return;
494 memcpy (buf, &hdr->filesize[0], 10); 509 done++;
495 buf[10] = '\0'; 510 }
496 if (1 != sscanf (buf, "%10llu", &csize)) 511 if (0 == strncmp (&hdr->name[0],
497 return; 512 "debian-binary", strlen ("debian-binary")))
498 pos += sizeof (struct ObjectHeader); 513 {
499 if ((pos + csize > fsize) || (csize > fsize) || (pos + csize < pos)) 514 if (0 != ec->proc (ec->cls,
515 "deb",
516 EXTRACTOR_METATYPE_MIMETYPE,
517 EXTRACTOR_METAFORMAT_UTF8,
518 "text/plain",
519 "application/x-debian-package",
520 strlen ("application/x-debian-package") + 1))
500 return; 521 return;
501 if (0 == strncmp (&hdr->name[0], 522 done++;
502 "control.tar.gz",
503 strlen ("control.tar.gz")))
504 {
505 if (0 != processControlTGZ (ec,
506 csize))
507 return;
508 done++;
509 }
510 if (0 == strncmp (&hdr->name[0],
511 "debian-binary", strlen ("debian-binary")))
512 {
513 if (0 != ec->proc (ec->cls,
514 "deb",
515 EXTRACTOR_METATYPE_MIMETYPE,
516 EXTRACTOR_METAFORMAT_UTF8,
517 "text/plain",
518 "application/x-debian-package",
519 strlen ("application/x-debian-package")+1))
520 return;
521 done++;
522 }
523 pos += csize;
524 if (2 == done)
525 break; /* no need to process the rest of the archive */
526 } 523 }
524 pos += csize;
525 if (2 == done)
526 break; /* no need to process the rest of the archive */
527 }
527} 528}
528 529
530
529/* end of deb_extractor.c */ 531/* end of deb_extractor.c */