diff options
Diffstat (limited to 'src/util/container_meta_data.c')
-rw-r--r-- | src/util/container_meta_data.c | 889 |
1 files changed, 423 insertions, 466 deletions
diff --git a/src/util/container_meta_data.c b/src/util/container_meta_data.c index 9d20f8dc5..64a58e133 100644 --- a/src/util/container_meta_data.c +++ b/src/util/container_meta_data.c | |||
@@ -39,7 +39,7 @@ struct MetaItem | |||
39 | { | 39 | { |
40 | /** | 40 | /** |
41 | * This is a linked list. | 41 | * This is a linked list. |
42 | */ | 42 | */ |
43 | struct MetaItem *next; | 43 | struct MetaItem *next; |
44 | 44 | ||
45 | /** | 45 | /** |
@@ -160,10 +160,10 @@ GNUNET_CONTAINER_meta_data_destroy (struct GNUNET_CONTAINER_MetaData *md) | |||
160 | if (md == NULL) | 160 | if (md == NULL) |
161 | return; | 161 | return; |
162 | while (NULL != (item = md->items)) | 162 | while (NULL != (item = md->items)) |
163 | { | 163 | { |
164 | md->items = item->next; | 164 | md->items = item->next; |
165 | meta_item_free (item); | 165 | meta_item_free (item); |
166 | } | 166 | } |
167 | GNUNET_free_non_null (md->sbuf); | 167 | GNUNET_free_non_null (md->sbuf); |
168 | GNUNET_free (md); | 168 | GNUNET_free (md); |
169 | } | 169 | } |
@@ -174,7 +174,7 @@ GNUNET_CONTAINER_meta_data_destroy (struct GNUNET_CONTAINER_MetaData *md) | |||
174 | * | 174 | * |
175 | * @param md metadata to manipulate | 175 | * @param md metadata to manipulate |
176 | */ | 176 | */ |
177 | void | 177 | void |
178 | GNUNET_CONTAINER_meta_data_clear (struct GNUNET_CONTAINER_MetaData *md) | 178 | GNUNET_CONTAINER_meta_data_clear (struct GNUNET_CONTAINER_MetaData *md) |
179 | { | 179 | { |
180 | struct MetaItem *item; | 180 | struct MetaItem *item; |
@@ -182,10 +182,10 @@ GNUNET_CONTAINER_meta_data_clear (struct GNUNET_CONTAINER_MetaData *md) | |||
182 | if (md == NULL) | 182 | if (md == NULL) |
183 | return; | 183 | return; |
184 | while (NULL != (item = md->items)) | 184 | while (NULL != (item = md->items)) |
185 | { | 185 | { |
186 | md->items = item->next; | 186 | md->items = item->next; |
187 | meta_item_free (item); | 187 | meta_item_free (item); |
188 | } | 188 | } |
189 | GNUNET_free_non_null (md->sbuf); | 189 | GNUNET_free_non_null (md->sbuf); |
190 | memset (md, 0, sizeof (struct GNUNET_CONTAINER_MetaData)); | 190 | memset (md, 0, sizeof (struct GNUNET_CONTAINER_MetaData)); |
191 | } | 191 | } |
@@ -219,27 +219,25 @@ GNUNET_CONTAINER_meta_data_test_equal (const struct GNUNET_CONTAINER_MetaData | |||
219 | 219 | ||
220 | i = md1->items; | 220 | i = md1->items; |
221 | while (NULL != i) | 221 | while (NULL != i) |
222 | { | ||
223 | found = GNUNET_NO; | ||
224 | j = md2->items; | ||
225 | while (NULL != j) | ||
222 | { | 226 | { |
223 | found = GNUNET_NO; | 227 | if ((i->type == j->type) && |
224 | j = md2->items; | 228 | (i->format == j->format) && |
225 | while (NULL != j) | 229 | (i->data_size == j->data_size) && |
226 | { | 230 | (0 == memcmp (i->data, j->data, i->data_size))) |
227 | if ( (i->type == j->type) && | 231 | { |
228 | (i->format == j->format) && | 232 | found = GNUNET_YES; |
229 | (i->data_size == j->data_size) && | 233 | break; |
230 | (0 == memcmp (i->data, | 234 | } |
231 | j->data, | 235 | j = j->next; |
232 | i->data_size))) | ||
233 | { | ||
234 | found = GNUNET_YES; | ||
235 | break; | ||
236 | } | ||
237 | j = j->next; | ||
238 | } | ||
239 | if (found == GNUNET_NO) | ||
240 | return GNUNET_NO; | ||
241 | i = i->next; | ||
242 | } | 236 | } |
237 | if (found == GNUNET_NO) | ||
238 | return GNUNET_NO; | ||
239 | i = i->next; | ||
240 | } | ||
243 | return GNUNET_YES; | 241 | return GNUNET_YES; |
244 | } | 242 | } |
245 | 243 | ||
@@ -264,12 +262,11 @@ GNUNET_CONTAINER_meta_data_test_equal (const struct GNUNET_CONTAINER_MetaData | |||
264 | */ | 262 | */ |
265 | int | 263 | int |
266 | GNUNET_CONTAINER_meta_data_insert (struct GNUNET_CONTAINER_MetaData *md, | 264 | GNUNET_CONTAINER_meta_data_insert (struct GNUNET_CONTAINER_MetaData *md, |
267 | const char *plugin_name, | 265 | const char *plugin_name, |
268 | enum EXTRACTOR_MetaType type, | 266 | enum EXTRACTOR_MetaType type, |
269 | enum EXTRACTOR_MetaFormat format, | 267 | enum EXTRACTOR_MetaFormat format, |
270 | const char *data_mime_type, | 268 | const char *data_mime_type, |
271 | const char *data, | 269 | const char *data, size_t data_len) |
272 | size_t data_len) | ||
273 | { | 270 | { |
274 | struct MetaItem *prev; | 271 | struct MetaItem *prev; |
275 | struct MetaItem *pos; | 272 | struct MetaItem *pos; |
@@ -279,32 +276,29 @@ GNUNET_CONTAINER_meta_data_insert (struct GNUNET_CONTAINER_MetaData *md, | |||
279 | prev = NULL; | 276 | prev = NULL; |
280 | pos = md->items; | 277 | pos = md->items; |
281 | while (NULL != pos) | 278 | while (NULL != pos) |
279 | { | ||
280 | if (pos->data_size < data_len) | ||
281 | break; | ||
282 | if ((pos->type == type) && | ||
283 | (pos->data_size == data_len) && | ||
284 | (0 == memcmp (pos->data, data, data_len))) | ||
282 | { | 285 | { |
283 | if (pos->data_size < data_len) | 286 | if ((pos->mime_type == NULL) && (data_mime_type != NULL)) |
284 | break; | 287 | { |
285 | if ( (pos->type == type) && | 288 | pos->mime_type = GNUNET_strdup (data_mime_type); |
286 | (pos->data_size == data_len) && | 289 | invalidate_sbuf (md); |
287 | (0 == memcmp (pos->data, | 290 | } |
288 | data, | 291 | if ((pos->format == EXTRACTOR_METAFORMAT_C_STRING) && |
289 | data_len))) | 292 | (format == EXTRACTOR_METAFORMAT_UTF8)) |
290 | { | 293 | { |
291 | if ( (pos->mime_type == NULL) && | 294 | pos->format = EXTRACTOR_METAFORMAT_UTF8; |
292 | (data_mime_type != NULL) ) | 295 | invalidate_sbuf (md); |
293 | { | 296 | } |
294 | pos->mime_type = GNUNET_strdup (data_mime_type); | 297 | return GNUNET_SYSERR; |
295 | invalidate_sbuf (md); | ||
296 | } | ||
297 | if ( (pos->format == EXTRACTOR_METAFORMAT_C_STRING) && | ||
298 | (format == EXTRACTOR_METAFORMAT_UTF8) ) | ||
299 | { | ||
300 | pos->format = EXTRACTOR_METAFORMAT_UTF8; | ||
301 | invalidate_sbuf (md); | ||
302 | } | ||
303 | return GNUNET_SYSERR; | ||
304 | } | ||
305 | prev = pos; | ||
306 | pos = pos->next; | ||
307 | } | 298 | } |
299 | prev = pos; | ||
300 | pos = pos->next; | ||
301 | } | ||
308 | md->item_count++; | 302 | md->item_count++; |
309 | i = GNUNET_malloc (sizeof (struct MetaItem)); | 303 | i = GNUNET_malloc (sizeof (struct MetaItem)); |
310 | i->type = type; | 304 | i->type = type; |
@@ -315,24 +309,24 @@ GNUNET_CONTAINER_meta_data_insert (struct GNUNET_CONTAINER_MetaData *md, | |||
315 | md->items = i; | 309 | md->items = i; |
316 | else | 310 | else |
317 | prev->next = i; | 311 | prev->next = i; |
318 | i->mime_type = (data_mime_type == NULL) ? NULL : GNUNET_strdup (data_mime_type); | 312 | i->mime_type = |
313 | (data_mime_type == NULL) ? NULL : GNUNET_strdup (data_mime_type); | ||
319 | i->plugin_name = (plugin_name == NULL) ? NULL : GNUNET_strdup (plugin_name); | 314 | i->plugin_name = (plugin_name == NULL) ? NULL : GNUNET_strdup (plugin_name); |
320 | i->data = GNUNET_malloc (data_len); | 315 | i->data = GNUNET_malloc (data_len); |
321 | memcpy (i->data, data, data_len); | 316 | memcpy (i->data, data, data_len); |
322 | /* change OS native dir separators to unix '/' and others to '_' */ | 317 | /* change OS native dir separators to unix '/' and others to '_' */ |
323 | if (type == EXTRACTOR_METATYPE_FILENAME) | 318 | if (type == EXTRACTOR_METATYPE_FILENAME) |
319 | { | ||
320 | p = i->data; | ||
321 | while ((*p != '\0') && (p < i->data + data_len)) | ||
324 | { | 322 | { |
325 | p = i->data; | 323 | if (*p == DIR_SEPARATOR) |
326 | while ( (*p != '\0') && | 324 | *p = '/'; |
327 | (p < i->data + data_len) ) | 325 | else if (*p == '\\') |
328 | { | 326 | *p = '_'; |
329 | if (*p == DIR_SEPARATOR) | 327 | p++; |
330 | *p = '/'; | ||
331 | else if (*p == '\\') | ||
332 | *p = '_'; | ||
333 | p++; | ||
334 | } | ||
335 | } | 328 | } |
329 | } | ||
336 | invalidate_sbuf (md); | 330 | invalidate_sbuf (md); |
337 | return GNUNET_OK; | 331 | return GNUNET_OK; |
338 | } | 332 | } |
@@ -353,20 +347,19 @@ GNUNET_CONTAINER_meta_data_insert (struct GNUNET_CONTAINER_MetaData *md, | |||
353 | * @param data actual meta-data found | 347 | * @param data actual meta-data found |
354 | * @param data_len number of bytes in data | 348 | * @param data_len number of bytes in data |
355 | * @return 0 (to continue) | 349 | * @return 0 (to continue) |
356 | */ | 350 | */ |
357 | static int | 351 | static int |
358 | merge_helper(void *cls, | 352 | merge_helper (void *cls, |
359 | const char *plugin_name, | 353 | const char *plugin_name, |
360 | enum EXTRACTOR_MetaType type, | 354 | enum EXTRACTOR_MetaType type, |
361 | enum EXTRACTOR_MetaFormat format, | 355 | enum EXTRACTOR_MetaFormat format, |
362 | const char *data_mime_type, | 356 | const char *data_mime_type, const char *data, size_t data_len) |
363 | const char *data, | ||
364 | size_t data_len) | ||
365 | { | 357 | { |
366 | struct GNUNET_CONTAINER_MetaData *md = cls; | 358 | struct GNUNET_CONTAINER_MetaData *md = cls; |
359 | |||
367 | (void) GNUNET_CONTAINER_meta_data_insert (md, plugin_name, | 360 | (void) GNUNET_CONTAINER_meta_data_insert (md, plugin_name, |
368 | type, format, | 361 | type, format, |
369 | data_mime_type, data, data_len); | 362 | data_mime_type, data, data_len); |
370 | return 0; | 363 | return 0; |
371 | } | 364 | } |
372 | 365 | ||
@@ -378,9 +371,9 @@ merge_helper(void *cls, | |||
378 | * @param md metadata to extend | 371 | * @param md metadata to extend |
379 | * @param in metadata to merge | 372 | * @param in metadata to merge |
380 | */ | 373 | */ |
381 | void | 374 | void |
382 | GNUNET_CONTAINER_meta_data_merge (struct GNUNET_CONTAINER_MetaData *md, | 375 | GNUNET_CONTAINER_meta_data_merge (struct GNUNET_CONTAINER_MetaData *md, |
383 | const struct GNUNET_CONTAINER_MetaData *in) | 376 | const struct GNUNET_CONTAINER_MetaData *in) |
384 | { | 377 | { |
385 | GNUNET_CONTAINER_meta_data_iterate (in, &merge_helper, md); | 378 | GNUNET_CONTAINER_meta_data_iterate (in, &merge_helper, md); |
386 | } | 379 | } |
@@ -398,9 +391,8 @@ GNUNET_CONTAINER_meta_data_merge (struct GNUNET_CONTAINER_MetaData *md, | |||
398 | */ | 391 | */ |
399 | int | 392 | int |
400 | GNUNET_CONTAINER_meta_data_delete (struct GNUNET_CONTAINER_MetaData *md, | 393 | GNUNET_CONTAINER_meta_data_delete (struct GNUNET_CONTAINER_MetaData *md, |
401 | enum EXTRACTOR_MetaType type, | 394 | enum EXTRACTOR_MetaType type, |
402 | const char *data, | 395 | const char *data, size_t data_len) |
403 | size_t data_len) | ||
404 | { | 396 | { |
405 | struct MetaItem *pos; | 397 | struct MetaItem *pos; |
406 | struct MetaItem *prev; | 398 | struct MetaItem *prev; |
@@ -408,26 +400,24 @@ GNUNET_CONTAINER_meta_data_delete (struct GNUNET_CONTAINER_MetaData *md, | |||
408 | prev = NULL; | 400 | prev = NULL; |
409 | pos = md->items; | 401 | pos = md->items; |
410 | while (NULL != pos) | 402 | while (NULL != pos) |
403 | { | ||
404 | if ((pos->type == type) && | ||
405 | ((data == NULL) || | ||
406 | ((pos->data_size == data_len) && | ||
407 | (0 == memcmp (pos->data, data, data_len))))) | ||
411 | { | 408 | { |
412 | if ( (pos->type == type) && | 409 | if (prev == NULL) |
413 | ( (data == NULL) || | 410 | md->items = pos->next; |
414 | ( (pos->data_size == data_len) && | 411 | else |
415 | (0 == memcmp (pos->data, | 412 | prev->next = pos->next; |
416 | data, | 413 | meta_item_free (pos); |
417 | data_len))) ) ) | 414 | md->item_count--; |
418 | { | 415 | invalidate_sbuf (md); |
419 | if (prev == NULL) | 416 | return GNUNET_OK; |
420 | md->items = pos->next; | ||
421 | else | ||
422 | prev->next = pos->next; | ||
423 | meta_item_free (pos); | ||
424 | md->item_count--; | ||
425 | invalidate_sbuf (md); | ||
426 | return GNUNET_OK; | ||
427 | } | ||
428 | prev = pos; | ||
429 | pos = pos->next; | ||
430 | } | 417 | } |
418 | prev = pos; | ||
419 | pos = pos->next; | ||
420 | } | ||
431 | return GNUNET_SYSERR; | 421 | return GNUNET_SYSERR; |
432 | } | 422 | } |
433 | 423 | ||
@@ -440,25 +430,21 @@ GNUNET_CONTAINER_meta_data_delete (struct GNUNET_CONTAINER_MetaData *md, | |||
440 | */ | 430 | */ |
441 | void | 431 | void |
442 | GNUNET_CONTAINER_meta_data_add_publication_date (struct | 432 | GNUNET_CONTAINER_meta_data_add_publication_date (struct |
443 | GNUNET_CONTAINER_MetaData | 433 | GNUNET_CONTAINER_MetaData *md) |
444 | *md) | ||
445 | { | 434 | { |
446 | char *dat; | 435 | char *dat; |
447 | struct GNUNET_TIME_Absolute t; | 436 | struct GNUNET_TIME_Absolute t; |
448 | 437 | ||
449 | t = GNUNET_TIME_absolute_get (); | 438 | t = GNUNET_TIME_absolute_get (); |
450 | GNUNET_CONTAINER_meta_data_delete (md, | 439 | GNUNET_CONTAINER_meta_data_delete (md, |
451 | EXTRACTOR_METATYPE_PUBLICATION_DATE, | 440 | EXTRACTOR_METATYPE_PUBLICATION_DATE, |
452 | NULL, | 441 | NULL, 0); |
453 | 0); | ||
454 | dat = GNUNET_STRINGS_absolute_time_to_string (t); | 442 | dat = GNUNET_STRINGS_absolute_time_to_string (t); |
455 | GNUNET_CONTAINER_meta_data_insert (md, | 443 | GNUNET_CONTAINER_meta_data_insert (md, |
456 | "<gnunet>", | 444 | "<gnunet>", |
457 | EXTRACTOR_METATYPE_PUBLICATION_DATE, | 445 | EXTRACTOR_METATYPE_PUBLICATION_DATE, |
458 | EXTRACTOR_METAFORMAT_UTF8, | 446 | EXTRACTOR_METAFORMAT_UTF8, |
459 | "text/plain", | 447 | "text/plain", dat, strlen (dat) + 1); |
460 | dat, | ||
461 | strlen(dat)+1); | ||
462 | GNUNET_free (dat); | 448 | GNUNET_free (dat); |
463 | } | 449 | } |
464 | 450 | ||
@@ -473,9 +459,9 @@ GNUNET_CONTAINER_meta_data_add_publication_date (struct | |||
473 | */ | 459 | */ |
474 | int | 460 | int |
475 | GNUNET_CONTAINER_meta_data_iterate (const struct | 461 | GNUNET_CONTAINER_meta_data_iterate (const struct |
476 | GNUNET_CONTAINER_MetaData *md, | 462 | GNUNET_CONTAINER_MetaData *md, |
477 | EXTRACTOR_MetaDataProcessor | 463 | EXTRACTOR_MetaDataProcessor |
478 | iter, void *iter_cls) | 464 | iter, void *iter_cls) |
479 | { | 465 | { |
480 | struct MetaItem *pos; | 466 | struct MetaItem *pos; |
481 | 467 | ||
@@ -485,17 +471,14 @@ GNUNET_CONTAINER_meta_data_iterate (const struct | |||
485 | return md->item_count; | 471 | return md->item_count; |
486 | pos = md->items; | 472 | pos = md->items; |
487 | while (NULL != pos) | 473 | while (NULL != pos) |
488 | { | 474 | { |
489 | if (0 != iter (iter_cls, | 475 | if (0 != iter (iter_cls, |
490 | pos->plugin_name, | 476 | pos->plugin_name, |
491 | pos->type, | 477 | pos->type, |
492 | pos->format, | 478 | pos->format, pos->mime_type, pos->data, pos->data_size)) |
493 | pos->mime_type, | 479 | return md->item_count; |
494 | pos->data, | 480 | pos = pos->next; |
495 | pos->data_size)) | 481 | } |
496 | return md->item_count; | ||
497 | pos = pos->next; | ||
498 | } | ||
499 | return md->item_count; | 482 | return md->item_count; |
500 | } | 483 | } |
501 | 484 | ||
@@ -520,13 +503,13 @@ GNUNET_CONTAINER_meta_data_get_by_type (const struct GNUNET_CONTAINER_MetaData | |||
520 | return NULL; | 503 | return NULL; |
521 | pos = md->items; | 504 | pos = md->items; |
522 | while (NULL != pos) | 505 | while (NULL != pos) |
523 | { | 506 | { |
524 | if ( (type == pos->type) && | 507 | if ((type == pos->type) && |
525 | ( (pos->format == EXTRACTOR_METAFORMAT_UTF8) || | 508 | ((pos->format == EXTRACTOR_METAFORMAT_UTF8) || |
526 | (pos->format == EXTRACTOR_METAFORMAT_C_STRING) ) ) | 509 | (pos->format == EXTRACTOR_METAFORMAT_C_STRING))) |
527 | return GNUNET_strdup (pos->data); | 510 | return GNUNET_strdup (pos->data); |
528 | pos = pos->next; | 511 | pos = pos->next; |
529 | } | 512 | } |
530 | return NULL; | 513 | return NULL; |
531 | } | 514 | } |
532 | 515 | ||
@@ -556,14 +539,15 @@ GNUNET_CONTAINER_meta_data_get_first_by_types (const struct | |||
556 | ret = NULL; | 539 | ret = NULL; |
557 | va_start (args, md); | 540 | va_start (args, md); |
558 | while (1) | 541 | while (1) |
559 | { | 542 | { |
560 | type = va_arg (args, enum EXTRACTOR_MetaType); | 543 | type = va_arg (args, enum EXTRACTOR_MetaType); |
561 | if (type == -1) | 544 | |
562 | break; | 545 | if (type == -1) |
563 | ret = GNUNET_CONTAINER_meta_data_get_by_type (md, type); | 546 | break; |
564 | if (ret != NULL) | 547 | ret = GNUNET_CONTAINER_meta_data_get_by_type (md, type); |
565 | break; | 548 | if (ret != NULL) |
566 | } | 549 | break; |
550 | } | ||
567 | va_end (args); | 551 | va_end (args); |
568 | return ret; | 552 | return ret; |
569 | } | 553 | } |
@@ -590,22 +574,21 @@ GNUNET_CONTAINER_meta_data_get_thumbnail (const struct | |||
590 | match = NULL; | 574 | match = NULL; |
591 | pos = md->items; | 575 | pos = md->items; |
592 | while (NULL != pos) | 576 | while (NULL != pos) |
593 | { | 577 | { |
594 | if ( (NULL != pos->mime_type) && | 578 | if ((NULL != pos->mime_type) && |
595 | (0 == strncasecmp ("image/", pos->mime_type, | 579 | (0 == strncasecmp ("image/", pos->mime_type, |
596 | strlen("image/"))) && | 580 | strlen ("image/"))) && |
597 | (pos->format == EXTRACTOR_METAFORMAT_BINARY) ) | 581 | (pos->format == EXTRACTOR_METAFORMAT_BINARY)) |
598 | { | 582 | { |
599 | if (match == NULL) | 583 | if (match == NULL) |
600 | match = pos; | 584 | match = pos; |
601 | else if ( (match->type != EXTRACTOR_METATYPE_THUMBNAIL) && | 585 | else if ((match->type != EXTRACTOR_METATYPE_THUMBNAIL) && |
602 | (pos->type == EXTRACTOR_METATYPE_THUMBNAIL) ) | 586 | (pos->type == EXTRACTOR_METATYPE_THUMBNAIL)) |
603 | match = pos; | 587 | match = pos; |
604 | } | ||
605 | pos = pos->next; | ||
606 | } | 588 | } |
607 | if ( (match == NULL) || | 589 | pos = pos->next; |
608 | (match->data_size == 0) ) | 590 | } |
591 | if ((match == NULL) || (match->data_size == 0)) | ||
609 | return 0; | 592 | return 0; |
610 | *thumb = GNUNET_malloc (match->data_size); | 593 | *thumb = GNUNET_malloc (match->data_size); |
611 | memcpy (*thumb, match->data, match->data_size); | 594 | memcpy (*thumb, match->data, match->data_size); |
@@ -631,16 +614,15 @@ GNUNET_CONTAINER_meta_data_duplicate (const struct GNUNET_CONTAINER_MetaData | |||
631 | ret = GNUNET_CONTAINER_meta_data_create (); | 614 | ret = GNUNET_CONTAINER_meta_data_create (); |
632 | pos = md->items; | 615 | pos = md->items; |
633 | while (NULL != pos) | 616 | while (NULL != pos) |
634 | { | 617 | { |
635 | GNUNET_CONTAINER_meta_data_insert (ret, | 618 | GNUNET_CONTAINER_meta_data_insert (ret, |
636 | pos->plugin_name, | 619 | pos->plugin_name, |
637 | pos->type, | 620 | pos->type, |
638 | pos->format, | 621 | pos->format, |
639 | pos->mime_type, | 622 | pos->mime_type, |
640 | pos->data, | 623 | pos->data, pos->data_size); |
641 | pos->data_size); | 624 | pos = pos->next; |
642 | pos = pos->next; | 625 | } |
643 | } | ||
644 | return ret; | 626 | return ret; |
645 | } | 627 | } |
646 | 628 | ||
@@ -660,10 +642,8 @@ GNUNET_CONTAINER_meta_data_duplicate (const struct GNUNET_CONTAINER_MetaData | |||
660 | * GNUNET_NO if compression did not help | 642 | * GNUNET_NO if compression did not help |
661 | */ | 643 | */ |
662 | static int | 644 | static int |
663 | try_compression (const char *data, | 645 | try_compression (const char *data, |
664 | size_t oldSize, | 646 | size_t oldSize, char **result, size_t * newSize) |
665 | char **result, | ||
666 | size_t *newSize) | ||
667 | { | 647 | { |
668 | char *tmp; | 648 | char *tmp; |
669 | uLongf dlen; | 649 | uLongf dlen; |
@@ -673,19 +653,19 @@ try_compression (const char *data, | |||
673 | #else | 653 | #else |
674 | dlen = oldSize + (oldSize / 100) + 20; | 654 | dlen = oldSize + (oldSize / 100) + 20; |
675 | /* documentation says 100.1% oldSize + 12 bytes, but we | 655 | /* documentation says 100.1% oldSize + 12 bytes, but we |
676 | should be able to overshoot by more to be safe */ | 656 | * should be able to overshoot by more to be safe */ |
677 | #endif | 657 | #endif |
678 | tmp = GNUNET_malloc (dlen); | 658 | tmp = GNUNET_malloc (dlen); |
679 | if (Z_OK == compress2 ((Bytef *) tmp, | 659 | if (Z_OK == compress2 ((Bytef *) tmp, |
680 | &dlen, (const Bytef *) data, oldSize, 9)) | 660 | &dlen, (const Bytef *) data, oldSize, 9)) |
661 | { | ||
662 | if (dlen < oldSize) | ||
681 | { | 663 | { |
682 | if (dlen < oldSize) | 664 | *result = tmp; |
683 | { | 665 | *newSize = dlen; |
684 | *result = tmp; | 666 | return GNUNET_YES; |
685 | *newSize = dlen; | ||
686 | return GNUNET_YES; | ||
687 | } | ||
688 | } | 667 | } |
668 | } | ||
689 | GNUNET_free (tmp); | 669 | GNUNET_free (tmp); |
690 | return GNUNET_NO; | 670 | return GNUNET_NO; |
691 | } | 671 | } |
@@ -744,7 +724,7 @@ struct MetaDataEntry | |||
744 | { | 724 | { |
745 | /** | 725 | /** |
746 | * Meta data type. Corresponds to an 'enum EXTRACTOR_MetaType' | 726 | * Meta data type. Corresponds to an 'enum EXTRACTOR_MetaType' |
747 | */ | 727 | */ |
748 | uint32_t type; | 728 | uint32_t type; |
749 | 729 | ||
750 | /** | 730 | /** |
@@ -793,8 +773,8 @@ GNUNET_CONTAINER_meta_data_serialize (const struct GNUNET_CONTAINER_MetaData | |||
793 | { | 773 | { |
794 | struct GNUNET_CONTAINER_MetaData *vmd; | 774 | struct GNUNET_CONTAINER_MetaData *vmd; |
795 | struct MetaItem *pos; | 775 | struct MetaItem *pos; |
796 | struct MetaDataHeader ihdr; | 776 | struct MetaDataHeader ihdr; |
797 | struct MetaDataHeader *hdr; | 777 | struct MetaDataHeader *hdr; |
798 | struct MetaDataEntry *ent; | 778 | struct MetaDataEntry *ent; |
799 | char *dst; | 779 | char *dst; |
800 | unsigned int i; | 780 | unsigned int i; |
@@ -814,78 +794,76 @@ GNUNET_CONTAINER_meta_data_serialize (const struct GNUNET_CONTAINER_MetaData | |||
814 | return GNUNET_SYSERR; /* far too small */ | 794 | return GNUNET_SYSERR; /* far too small */ |
815 | if (md == NULL) | 795 | if (md == NULL) |
816 | return 0; | 796 | return 0; |
817 | 797 | ||
818 | if (md->sbuf != NULL) | 798 | if (md->sbuf != NULL) |
799 | { | ||
800 | /* try to use serialization cache */ | ||
801 | if (md->sbuf_size <= max) | ||
819 | { | 802 | { |
820 | /* try to use serialization cache */ | 803 | if (NULL == *target) |
821 | if (md->sbuf_size <= max) | 804 | *target = GNUNET_malloc (md->sbuf_size); |
822 | { | 805 | memcpy (*target, md->sbuf, md->sbuf_size); |
823 | if (NULL == *target) | 806 | return md->sbuf_size; |
824 | *target = GNUNET_malloc (md->sbuf_size); | ||
825 | memcpy (*target, | ||
826 | md->sbuf, | ||
827 | md->sbuf_size); | ||
828 | return md->sbuf_size; | ||
829 | } | ||
830 | if (0 == (opt & GNUNET_CONTAINER_META_DATA_SERIALIZE_PART)) | ||
831 | return GNUNET_SYSERR; /* can say that this will fail */ | ||
832 | /* need to compute a partial serialization, sbuf useless ... */ | ||
833 | } | 807 | } |
834 | dst = NULL; | 808 | if (0 == (opt & GNUNET_CONTAINER_META_DATA_SERIALIZE_PART)) |
809 | return GNUNET_SYSERR; /* can say that this will fail */ | ||
810 | /* need to compute a partial serialization, sbuf useless ... */ | ||
811 | } | ||
812 | dst = NULL; | ||
835 | msize = 0; | 813 | msize = 0; |
836 | pos = md->items; | 814 | pos = md->items; |
837 | while (NULL != pos) | 815 | while (NULL != pos) |
838 | { | 816 | { |
839 | msize += sizeof (struct MetaDataEntry); | 817 | msize += sizeof (struct MetaDataEntry); |
840 | msize += pos->data_size; | 818 | msize += pos->data_size; |
841 | if (pos->plugin_name != NULL) | 819 | if (pos->plugin_name != NULL) |
842 | msize += strlen (pos->plugin_name) + 1; | 820 | msize += strlen (pos->plugin_name) + 1; |
843 | if (pos->mime_type != NULL) | 821 | if (pos->mime_type != NULL) |
844 | msize += strlen (pos->mime_type) + 1; | 822 | msize += strlen (pos->mime_type) + 1; |
845 | pos = pos->next; | 823 | pos = pos->next; |
846 | } | 824 | } |
847 | size = (size_t) msize; | 825 | size = (size_t) msize; |
848 | if (size != msize) | 826 | if (size != msize) |
849 | { | 827 | { |
850 | GNUNET_break (0); /* integer overflow */ | 828 | GNUNET_break (0); /* integer overflow */ |
851 | return GNUNET_SYSERR; | 829 | return GNUNET_SYSERR; |
852 | } | 830 | } |
853 | if (size >= GNUNET_MAX_MALLOC_CHECKED) | 831 | if (size >= GNUNET_MAX_MALLOC_CHECKED) |
854 | { | 832 | { |
855 | /* too large to be processed */ | 833 | /* too large to be processed */ |
856 | return GNUNET_SYSERR; | 834 | return GNUNET_SYSERR; |
857 | } | 835 | } |
858 | ent = GNUNET_malloc (size); | 836 | ent = GNUNET_malloc (size); |
859 | mdata = (char *) &ent[md->item_count]; | 837 | mdata = (char *) &ent[md->item_count]; |
860 | off = size - (md->item_count * sizeof(struct MetaDataEntry)); | 838 | off = size - (md->item_count * sizeof (struct MetaDataEntry)); |
861 | i = 0; | 839 | i = 0; |
862 | pos = md->items; | 840 | pos = md->items; |
863 | while (NULL != pos) | 841 | while (NULL != pos) |
864 | { | 842 | { |
865 | ent[i].type = htonl ((uint32_t) pos->type); | 843 | ent[i].type = htonl ((uint32_t) pos->type); |
866 | ent[i].format = htonl ((uint32_t) pos->format); | 844 | ent[i].format = htonl ((uint32_t) pos->format); |
867 | ent[i].data_size = htonl ((uint32_t) pos->data_size); | 845 | ent[i].data_size = htonl ((uint32_t) pos->data_size); |
868 | if (pos->plugin_name == NULL) | 846 | if (pos->plugin_name == NULL) |
869 | plen = 0; | 847 | plen = 0; |
870 | else | 848 | else |
871 | plen = strlen (pos->plugin_name) + 1; | 849 | plen = strlen (pos->plugin_name) + 1; |
872 | ent[i].plugin_name_len = htonl ( (uint32_t) plen); | 850 | ent[i].plugin_name_len = htonl ((uint32_t) plen); |
873 | if (pos->mime_type == NULL) | 851 | if (pos->mime_type == NULL) |
874 | mlen = 0; | 852 | mlen = 0; |
875 | else | 853 | else |
876 | mlen = strlen (pos->mime_type) + 1; | 854 | mlen = strlen (pos->mime_type) + 1; |
877 | ent[i].mime_type_len = htonl ((uint32_t) mlen); | 855 | ent[i].mime_type_len = htonl ((uint32_t) mlen); |
878 | off -= pos->data_size; | 856 | off -= pos->data_size; |
879 | memcpy (&mdata[off], pos->data, pos->data_size); | 857 | memcpy (&mdata[off], pos->data, pos->data_size); |
880 | off -= plen; | 858 | off -= plen; |
881 | if (pos->plugin_name != NULL) | 859 | if (pos->plugin_name != NULL) |
882 | memcpy (&mdata[off], pos->plugin_name, plen); | 860 | memcpy (&mdata[off], pos->plugin_name, plen); |
883 | off -= mlen; | 861 | off -= mlen; |
884 | if (pos->mime_type != NULL) | 862 | if (pos->mime_type != NULL) |
885 | memcpy (&mdata[off], pos->mime_type, mlen); | 863 | memcpy (&mdata[off], pos->mime_type, mlen); |
886 | i++; | 864 | i++; |
887 | pos = pos->next; | 865 | pos = pos->next; |
888 | } | 866 | } |
889 | GNUNET_assert (off == 0); | 867 | GNUNET_assert (off == 0); |
890 | 868 | ||
891 | clen = 0; | 869 | clen = 0; |
@@ -894,115 +872,102 @@ GNUNET_CONTAINER_meta_data_serialize (const struct GNUNET_CONTAINER_MetaData | |||
894 | i = 0; | 872 | i = 0; |
895 | pos = md->items; | 873 | pos = md->items; |
896 | while (pos != NULL) | 874 | while (pos != NULL) |
897 | { | 875 | { |
898 | comp = GNUNET_NO; | 876 | comp = GNUNET_NO; |
899 | if (0 == (opt & GNUNET_CONTAINER_META_DATA_SERIALIZE_NO_COMPRESS)) | 877 | if (0 == (opt & GNUNET_CONTAINER_META_DATA_SERIALIZE_NO_COMPRESS)) |
900 | comp = try_compression ((const char*) &ent[i], | 878 | comp = try_compression ((const char *) &ent[i], left, &cdata, &clen); |
901 | left, | 879 | |
902 | &cdata, | 880 | if ((md->sbuf == NULL) && (i == 0)) |
903 | &clen); | 881 | { |
904 | 882 | /* fill 'sbuf'; this "modifies" md, but since this is only | |
905 | if ( (md->sbuf == NULL) && | 883 | * an internal cache we will cast away the 'const' instead |
906 | (i == 0) ) | 884 | * of making the API look strange. */ |
907 | { | 885 | vmd = (struct GNUNET_CONTAINER_MetaData *) md; |
908 | /* fill 'sbuf'; this "modifies" md, but since this is only | 886 | hdr = GNUNET_malloc (left + sizeof (struct MetaDataHeader)); |
909 | an internal cache we will cast away the 'const' instead | 887 | hdr->size = htonl (left); |
910 | of making the API look strange. */ | 888 | hdr->entries = htonl (md->item_count); |
911 | vmd = (struct GNUNET_CONTAINER_MetaData*) md; | 889 | if (GNUNET_YES == comp) |
912 | hdr = GNUNET_malloc (left + sizeof (struct MetaDataHeader)); | 890 | { |
913 | hdr->size = htonl (left); | 891 | GNUNET_assert (clen < left); |
914 | hdr->entries = htonl (md->item_count); | 892 | hdr->version = htonl (2 | HEADER_COMPRESSED); |
915 | if (GNUNET_YES == comp) | 893 | memcpy (&hdr[1], cdata, clen); |
916 | { | 894 | vmd->sbuf_size = clen + sizeof (struct MetaDataHeader); |
917 | GNUNET_assert (clen < left); | 895 | } |
918 | hdr->version = htonl (2 | HEADER_COMPRESSED); | 896 | else |
919 | memcpy (&hdr[1], | 897 | { |
920 | cdata, | 898 | hdr->version = htonl (2); |
921 | clen); | 899 | memcpy (&hdr[1], &ent[0], left); |
922 | vmd->sbuf_size = clen + sizeof (struct MetaDataHeader); | 900 | vmd->sbuf_size = left + sizeof (struct MetaDataHeader); |
923 | } | 901 | } |
924 | else | 902 | vmd->sbuf = (char *) hdr; |
925 | { | 903 | } |
926 | hdr->version = htonl (2); | 904 | |
927 | memcpy (&hdr[1], | 905 | if (((left + sizeof (struct MetaDataHeader)) <= max) || |
928 | &ent[0], | 906 | ((comp == GNUNET_YES) && (clen <= max))) |
929 | left); | 907 | { |
930 | vmd->sbuf_size = left + sizeof (struct MetaDataHeader); | 908 | /* success, this now fits! */ |
931 | } | 909 | if (GNUNET_YES == comp) |
932 | vmd->sbuf = (char*) hdr; | 910 | { |
933 | } | 911 | if (dst == NULL) |
934 | 912 | dst = GNUNET_malloc (clen + sizeof (struct MetaDataHeader)); | |
935 | if ( ( (left + sizeof (struct MetaDataHeader)) <= max) || | 913 | hdr = (struct MetaDataHeader *) dst; |
936 | ( (comp == GNUNET_YES) && | 914 | hdr->version = htonl (2 | HEADER_COMPRESSED); |
937 | (clen <= max)) ) | 915 | hdr->size = htonl (left); |
938 | { | 916 | hdr->entries = htonl (md->item_count - i); |
939 | /* success, this now fits! */ | 917 | memcpy (&dst[sizeof (struct MetaDataHeader)], cdata, clen); |
940 | if (GNUNET_YES == comp) | 918 | GNUNET_free (cdata); |
941 | { | 919 | GNUNET_free (ent); |
942 | if (dst == NULL) | 920 | rlen = clen + sizeof (struct MetaDataHeader); |
943 | dst = GNUNET_malloc (clen + sizeof (struct MetaDataHeader)); | 921 | } |
944 | hdr = (struct MetaDataHeader*) dst; | 922 | else |
945 | hdr->version = htonl (2 | HEADER_COMPRESSED); | 923 | { |
946 | hdr->size = htonl (left); | 924 | if (dst == NULL) |
947 | hdr->entries = htonl (md->item_count - i); | 925 | dst = GNUNET_malloc (left + sizeof (struct MetaDataHeader)); |
948 | memcpy (&dst[sizeof(struct MetaDataHeader)], | 926 | hdr = (struct MetaDataHeader *) dst; |
949 | cdata, | 927 | hdr->version = htonl (2); |
950 | clen); | 928 | hdr->entries = htonl (md->item_count - i); |
951 | GNUNET_free (cdata); | 929 | hdr->size = htonl (left); |
952 | GNUNET_free (ent); | 930 | memcpy (&dst[sizeof (struct MetaDataHeader)], &ent[i], left); |
953 | rlen = clen + sizeof (struct MetaDataHeader); | 931 | GNUNET_free (ent); |
954 | } | 932 | rlen = left + sizeof (struct MetaDataHeader); |
955 | else | 933 | } |
956 | { | 934 | if (NULL != *target) |
957 | if (dst == NULL) | 935 | { |
958 | dst = GNUNET_malloc (left + sizeof (struct MetaDataHeader)); | 936 | memcpy (*target, dst, clen + sizeof (struct MetaDataHeader)); |
959 | hdr = (struct MetaDataHeader*) dst; | 937 | GNUNET_free (dst); |
960 | hdr->version = htonl (2); | 938 | } |
961 | hdr->entries = htonl (md->item_count - i); | 939 | else |
962 | hdr->size = htonl (left); | 940 | { |
963 | memcpy (&dst[sizeof(struct MetaDataHeader)], | 941 | *target = dst; |
964 | &ent[i], | 942 | } |
965 | left); | 943 | return rlen; |
966 | GNUNET_free (ent); | 944 | } |
967 | rlen = left + sizeof (struct MetaDataHeader); | 945 | |
968 | } | 946 | if (0 == (opt & GNUNET_CONTAINER_META_DATA_SERIALIZE_PART)) |
969 | if (NULL != *target) | 947 | { |
970 | { | 948 | /* does not fit! */ |
971 | memcpy (*target, dst, clen + sizeof (struct MetaDataHeader)); | 949 | GNUNET_free (ent); |
972 | GNUNET_free (dst); | 950 | return GNUNET_SYSERR; |
973 | } | ||
974 | else | ||
975 | { | ||
976 | *target = dst; | ||
977 | } | ||
978 | return rlen; | ||
979 | } | ||
980 | |||
981 | if (0 == (opt & GNUNET_CONTAINER_META_DATA_SERIALIZE_PART)) | ||
982 | { | ||
983 | /* does not fit! */ | ||
984 | GNUNET_free (ent); | ||
985 | return GNUNET_SYSERR; | ||
986 | } | ||
987 | |||
988 | /* next iteration: ignore the corresponding meta data at the | ||
989 | end and try again without it */ | ||
990 | left -= sizeof (struct MetaDataEntry); | ||
991 | left -= pos->data_size; | ||
992 | if (pos->plugin_name != NULL) | ||
993 | left -= strlen (pos->plugin_name) + 1; | ||
994 | if (pos->mime_type != NULL) | ||
995 | left -= strlen (pos->mime_type) + 1; | ||
996 | pos = pos->next; | ||
997 | i++; | ||
998 | } | 951 | } |
952 | |||
953 | /* next iteration: ignore the corresponding meta data at the | ||
954 | * end and try again without it */ | ||
955 | left -= sizeof (struct MetaDataEntry); | ||
956 | left -= pos->data_size; | ||
957 | if (pos->plugin_name != NULL) | ||
958 | left -= strlen (pos->plugin_name) + 1; | ||
959 | if (pos->mime_type != NULL) | ||
960 | left -= strlen (pos->mime_type) + 1; | ||
961 | pos = pos->next; | ||
962 | i++; | ||
963 | } | ||
999 | GNUNET_free (ent); | 964 | GNUNET_free (ent); |
1000 | 965 | ||
1001 | /* nothing fit, only write header! */ | 966 | /* nothing fit, only write header! */ |
1002 | ihdr.version = htonl (2); | 967 | ihdr.version = htonl (2); |
1003 | ihdr.entries = htonl (0); | 968 | ihdr.entries = htonl (0); |
1004 | ihdr.size = htonl (0); | 969 | ihdr.size = htonl (0); |
1005 | if (*target == NULL) | 970 | if (*target == NULL) |
1006 | *target = GNUNET_malloc (sizeof (struct MetaDataHeader)); | 971 | *target = GNUNET_malloc (sizeof (struct MetaDataHeader)); |
1007 | memcpy (*target, &ihdr, sizeof (struct MetaDataHeader)); | 972 | memcpy (*target, &ihdr, sizeof (struct MetaDataHeader)); |
1008 | return sizeof (struct MetaDataHeader); | 973 | return sizeof (struct MetaDataHeader); |
@@ -1016,18 +981,19 @@ GNUNET_CONTAINER_meta_data_serialize (const struct GNUNET_CONTAINER_MetaData | |||
1016 | * @return number of bytes needed for serialization, -1 on error | 981 | * @return number of bytes needed for serialization, -1 on error |
1017 | */ | 982 | */ |
1018 | ssize_t | 983 | ssize_t |
1019 | GNUNET_CONTAINER_meta_data_get_serialized_size (const struct GNUNET_CONTAINER_MetaData *md) | 984 | GNUNET_CONTAINER_meta_data_get_serialized_size (const struct |
985 | GNUNET_CONTAINER_MetaData *md) | ||
1020 | { | 986 | { |
1021 | ssize_t ret; | 987 | ssize_t ret; |
1022 | char *ptr; | 988 | char *ptr; |
1023 | 989 | ||
1024 | if (md->sbuf != NULL) | 990 | if (md->sbuf != NULL) |
1025 | return md->sbuf_size; | 991 | return md->sbuf_size; |
1026 | ptr = NULL; | 992 | ptr = NULL; |
1027 | ret = GNUNET_CONTAINER_meta_data_serialize (md, | 993 | ret = GNUNET_CONTAINER_meta_data_serialize (md, |
1028 | &ptr, | 994 | &ptr, |
1029 | GNUNET_MAX_MALLOC_CHECKED, | 995 | GNUNET_MAX_MALLOC_CHECKED, |
1030 | GNUNET_CONTAINER_META_DATA_SERIALIZE_FULL); | 996 | GNUNET_CONTAINER_META_DATA_SERIALIZE_FULL); |
1031 | if (ret != -1) | 997 | if (ret != -1) |
1032 | GNUNET_free (ptr); | 998 | GNUNET_free (ptr); |
1033 | return ret; | 999 | return ret; |
@@ -1045,9 +1011,7 @@ GNUNET_CONTAINER_meta_data_get_serialized_size (const struct GNUNET_CONTAINER_Me | |||
1045 | * @return NULL on error | 1011 | * @return NULL on error |
1046 | */ | 1012 | */ |
1047 | static char * | 1013 | static char * |
1048 | decompress (const char *input, | 1014 | decompress (const char *input, size_t inputSize, size_t outputSize) |
1049 | size_t inputSize, | ||
1050 | size_t outputSize) | ||
1051 | { | 1015 | { |
1052 | char *output; | 1016 | char *output; |
1053 | uLongf olen; | 1017 | uLongf olen; |
@@ -1056,14 +1020,14 @@ decompress (const char *input, | |||
1056 | output = GNUNET_malloc (olen); | 1020 | output = GNUNET_malloc (olen); |
1057 | if (Z_OK == uncompress ((Bytef *) output, | 1021 | if (Z_OK == uncompress ((Bytef *) output, |
1058 | &olen, (const Bytef *) input, inputSize)) | 1022 | &olen, (const Bytef *) input, inputSize)) |
1059 | { | 1023 | { |
1060 | return output; | 1024 | return output; |
1061 | } | 1025 | } |
1062 | else | 1026 | else |
1063 | { | 1027 | { |
1064 | GNUNET_free (output); | 1028 | GNUNET_free (output); |
1065 | return NULL; | 1029 | return NULL; |
1066 | } | 1030 | } |
1067 | } | 1031 | } |
1068 | 1032 | ||
1069 | 1033 | ||
@@ -1100,136 +1064,129 @@ GNUNET_CONTAINER_meta_data_deserialize (const char *input, size_t size) | |||
1100 | 1064 | ||
1101 | if (size < sizeof (struct MetaDataHeader)) | 1065 | if (size < sizeof (struct MetaDataHeader)) |
1102 | return NULL; | 1066 | return NULL; |
1103 | memcpy (&hdr, | 1067 | memcpy (&hdr, input, sizeof (struct MetaDataHeader)); |
1104 | input, | ||
1105 | sizeof (struct MetaDataHeader)); | ||
1106 | version = ntohl (hdr.version) & HEADER_VERSION_MASK; | 1068 | version = ntohl (hdr.version) & HEADER_VERSION_MASK; |
1107 | compressed = (ntohl (hdr.version) & HEADER_COMPRESSED) != 0; | 1069 | compressed = (ntohl (hdr.version) & HEADER_COMPRESSED) != 0; |
1108 | 1070 | ||
1109 | if (version == 1) | 1071 | if (version == 1) |
1110 | return NULL; /* null pointer */ | 1072 | return NULL; /* null pointer */ |
1111 | if (version != 2) | 1073 | if (version != 2) |
1112 | { | 1074 | { |
1113 | GNUNET_break_op (0); /* unsupported version */ | 1075 | GNUNET_break_op (0); /* unsupported version */ |
1114 | return NULL; | 1076 | return NULL; |
1115 | } | 1077 | } |
1116 | 1078 | ||
1117 | ic = ntohl (hdr.entries); | 1079 | ic = ntohl (hdr.entries); |
1118 | dataSize = ntohl (hdr.size); | 1080 | dataSize = ntohl (hdr.size); |
1119 | if ((sizeof (struct MetaDataEntry) * ic) > dataSize) | 1081 | if ((sizeof (struct MetaDataEntry) * ic) > dataSize) |
1120 | { | 1082 | { |
1121 | GNUNET_break_op (0); | 1083 | GNUNET_break_op (0); |
1122 | return NULL; | 1084 | return NULL; |
1123 | } | 1085 | } |
1124 | 1086 | ||
1125 | if (compressed) | 1087 | if (compressed) |
1088 | { | ||
1089 | if (dataSize >= GNUNET_MAX_MALLOC_CHECKED) | ||
1126 | { | 1090 | { |
1127 | if (dataSize >= GNUNET_MAX_MALLOC_CHECKED) | 1091 | /* make sure we don't blow our memory limit because of a mal-formed |
1128 | { | 1092 | * message... */ |
1129 | /* make sure we don't blow our memory limit because of a mal-formed | 1093 | GNUNET_break_op (0); |
1130 | message... */ | 1094 | return NULL; |
1131 | GNUNET_break_op (0); | 1095 | } |
1132 | return NULL; | 1096 | data = |
1133 | } | ||
1134 | data = | ||
1135 | decompress ((const char *) &input[sizeof (struct MetaDataHeader)], | 1097 | decompress ((const char *) &input[sizeof (struct MetaDataHeader)], |
1136 | size - sizeof (struct MetaDataHeader), dataSize); | 1098 | size - sizeof (struct MetaDataHeader), dataSize); |
1137 | if (data == NULL) | 1099 | if (data == NULL) |
1138 | { | 1100 | { |
1139 | GNUNET_break_op (0); | 1101 | GNUNET_break_op (0); |
1140 | return NULL; | 1102 | return NULL; |
1141 | } | ||
1142 | cdata = data; | ||
1143 | } | 1103 | } |
1104 | cdata = data; | ||
1105 | } | ||
1144 | else | 1106 | else |
1107 | { | ||
1108 | data = NULL; | ||
1109 | cdata = (const char *) &input[sizeof (struct MetaDataHeader)]; | ||
1110 | if (dataSize != size - sizeof (struct MetaDataHeader)) | ||
1145 | { | 1111 | { |
1146 | data = NULL; | 1112 | GNUNET_break_op (0); |
1147 | cdata = (const char *) &input[sizeof (struct MetaDataHeader)]; | 1113 | return NULL; |
1148 | if (dataSize != size - sizeof (struct MetaDataHeader)) | ||
1149 | { | ||
1150 | GNUNET_break_op (0); | ||
1151 | return NULL; | ||
1152 | } | ||
1153 | } | 1114 | } |
1115 | } | ||
1154 | 1116 | ||
1155 | md = GNUNET_CONTAINER_meta_data_create (); | 1117 | md = GNUNET_CONTAINER_meta_data_create (); |
1156 | left = dataSize - ic * sizeof (struct MetaDataEntry); | 1118 | left = dataSize - ic * sizeof (struct MetaDataEntry); |
1157 | mdata = &cdata[ic * sizeof (struct MetaDataEntry)]; | 1119 | mdata = &cdata[ic * sizeof (struct MetaDataEntry)]; |
1158 | for (i=0;i<ic;i++) | 1120 | for (i = 0; i < ic; i++) |
1121 | { | ||
1122 | memcpy (&ent, | ||
1123 | &cdata[i * sizeof (struct MetaDataEntry)], | ||
1124 | sizeof (struct MetaDataEntry)); | ||
1125 | format = (enum EXTRACTOR_MetaFormat) ntohl (ent.format); | ||
1126 | if ((format != EXTRACTOR_METAFORMAT_UTF8) && | ||
1127 | (format != EXTRACTOR_METAFORMAT_C_STRING) && | ||
1128 | (format != EXTRACTOR_METAFORMAT_BINARY)) | ||
1159 | { | 1129 | { |
1160 | memcpy (&ent, | 1130 | GNUNET_break_op (0); |
1161 | &cdata[i * sizeof(struct MetaDataEntry)], | 1131 | break; |
1162 | sizeof (struct MetaDataEntry)); | 1132 | } |
1163 | format = (enum EXTRACTOR_MetaFormat) ntohl (ent.format); | 1133 | dlen = ntohl (ent.data_size); |
1164 | if ( (format != EXTRACTOR_METAFORMAT_UTF8) && | 1134 | plen = ntohl (ent.plugin_name_len); |
1165 | (format != EXTRACTOR_METAFORMAT_C_STRING) && | 1135 | mlen = ntohl (ent.mime_type_len); |
1166 | (format != EXTRACTOR_METAFORMAT_BINARY) ) | 1136 | if (dlen > left) |
1167 | { | 1137 | { |
1168 | GNUNET_break_op (0); | 1138 | GNUNET_break_op (0); |
1169 | break; | 1139 | break; |
1170 | } | 1140 | } |
1171 | dlen = ntohl (ent.data_size); | 1141 | left -= dlen; |
1172 | plen = ntohl (ent.plugin_name_len); | 1142 | meta_data = &mdata[left]; |
1173 | mlen = ntohl (ent.mime_type_len); | 1143 | if ((format == EXTRACTOR_METAFORMAT_UTF8) || |
1174 | if (dlen > left) | 1144 | (format == EXTRACTOR_METAFORMAT_C_STRING)) |
1175 | { | 1145 | { |
1176 | GNUNET_break_op (0); | 1146 | if ((dlen == 0) || (mdata[left + dlen - 1] != '\0')) |
1177 | break; | 1147 | { |
1178 | } | 1148 | GNUNET_break_op (0); |
1179 | left -= dlen; | 1149 | break; |
1180 | meta_data = &mdata[left]; | 1150 | } |
1181 | if ( (format == EXTRACTOR_METAFORMAT_UTF8) || | 1151 | } |
1182 | (format == EXTRACTOR_METAFORMAT_C_STRING) ) | 1152 | if (plen > left) |
1183 | { | 1153 | { |
1184 | if ( (dlen == 0) || | 1154 | GNUNET_break_op (0); |
1185 | (mdata[left + dlen - 1] != '\0') ) | 1155 | break; |
1186 | { | 1156 | } |
1187 | GNUNET_break_op (0); | 1157 | left -= plen; |
1188 | break; | 1158 | if ((plen > 0) && (mdata[left + plen - 1] != '\0')) |
1189 | } | 1159 | { |
1190 | } | 1160 | GNUNET_break_op (0); |
1191 | if (plen > left) | 1161 | break; |
1192 | { | 1162 | } |
1193 | GNUNET_break_op (0); | 1163 | if (plen == 0) |
1194 | break; | 1164 | plugin_name = NULL; |
1195 | } | 1165 | else |
1196 | left -= plen; | 1166 | plugin_name = &mdata[left]; |
1197 | if ( (plen > 0) && | 1167 | |
1198 | (mdata[left + plen - 1] != '\0') ) | 1168 | if (mlen > left) |
1199 | { | 1169 | { |
1200 | GNUNET_break_op (0); | 1170 | GNUNET_break_op (0); |
1201 | break; | 1171 | break; |
1202 | } | 1172 | } |
1203 | if (plen == 0) | 1173 | left -= mlen; |
1204 | plugin_name = NULL; | 1174 | if ((mlen > 0) && (mdata[left + mlen - 1] != '\0')) |
1205 | else | 1175 | { |
1206 | plugin_name = &mdata[left]; | 1176 | GNUNET_break_op (0); |
1207 | 1177 | break; | |
1208 | if (mlen > left) | ||
1209 | { | ||
1210 | GNUNET_break_op (0); | ||
1211 | break; | ||
1212 | } | ||
1213 | left -= mlen; | ||
1214 | if ( (mlen > 0) && | ||
1215 | (mdata[left + mlen - 1] != '\0') ) | ||
1216 | { | ||
1217 | GNUNET_break_op (0); | ||
1218 | break; | ||
1219 | } | ||
1220 | if (mlen == 0) | ||
1221 | mime_type = NULL; | ||
1222 | else | ||
1223 | mime_type = &mdata[left]; | ||
1224 | GNUNET_CONTAINER_meta_data_insert (md, | ||
1225 | plugin_name, | ||
1226 | (enum EXTRACTOR_MetaType) ntohl (ent.type), | ||
1227 | format, | ||
1228 | mime_type, | ||
1229 | meta_data, | ||
1230 | dlen); | ||
1231 | } | 1178 | } |
1232 | GNUNET_free_non_null (data); | 1179 | if (mlen == 0) |
1180 | mime_type = NULL; | ||
1181 | else | ||
1182 | mime_type = &mdata[left]; | ||
1183 | GNUNET_CONTAINER_meta_data_insert (md, | ||
1184 | plugin_name, | ||
1185 | (enum EXTRACTOR_MetaType) | ||
1186 | ntohl (ent.type), format, mime_type, | ||
1187 | meta_data, dlen); | ||
1188 | } | ||
1189 | GNUNET_free_non_null (data); | ||
1233 | return md; | 1190 | return md; |
1234 | } | 1191 | } |
1235 | 1192 | ||