diff options
Diffstat (limited to 'src/util/container_meta_data.c')
-rw-r--r-- | src/util/container_meta_data.c | 792 |
1 files changed, 395 insertions, 397 deletions
diff --git a/src/util/container_meta_data.c b/src/util/container_meta_data.c index 1ea77f63a..c2ec01c04 100644 --- a/src/util/container_meta_data.c +++ b/src/util/container_meta_data.c | |||
@@ -162,10 +162,10 @@ GNUNET_CONTAINER_meta_data_destroy (struct GNUNET_CONTAINER_MetaData *md) | |||
162 | if (md == NULL) | 162 | if (md == NULL) |
163 | return; | 163 | return; |
164 | while (NULL != (item = md->items)) | 164 | while (NULL != (item = md->items)) |
165 | { | 165 | { |
166 | md->items = item->next; | 166 | md->items = item->next; |
167 | meta_item_free (item); | 167 | meta_item_free (item); |
168 | } | 168 | } |
169 | GNUNET_free_non_null (md->sbuf); | 169 | GNUNET_free_non_null (md->sbuf); |
170 | GNUNET_free (md); | 170 | GNUNET_free (md); |
171 | } | 171 | } |
@@ -184,10 +184,10 @@ GNUNET_CONTAINER_meta_data_clear (struct GNUNET_CONTAINER_MetaData *md) | |||
184 | if (md == NULL) | 184 | if (md == NULL) |
185 | return; | 185 | return; |
186 | while (NULL != (item = md->items)) | 186 | while (NULL != (item = md->items)) |
187 | { | 187 | { |
188 | md->items = item->next; | 188 | md->items = item->next; |
189 | meta_item_free (item); | 189 | meta_item_free (item); |
190 | } | 190 | } |
191 | GNUNET_free_non_null (md->sbuf); | 191 | GNUNET_free_non_null (md->sbuf); |
192 | memset (md, 0, sizeof (struct GNUNET_CONTAINER_MetaData)); | 192 | memset (md, 0, sizeof (struct GNUNET_CONTAINER_MetaData)); |
193 | } | 193 | } |
@@ -206,9 +206,9 @@ GNUNET_CONTAINER_meta_data_clear (struct GNUNET_CONTAINER_MetaData *md) | |||
206 | */ | 206 | */ |
207 | int | 207 | int |
208 | GNUNET_CONTAINER_meta_data_test_equal (const struct GNUNET_CONTAINER_MetaData | 208 | GNUNET_CONTAINER_meta_data_test_equal (const struct GNUNET_CONTAINER_MetaData |
209 | *md1, | 209 | *md1, |
210 | const struct GNUNET_CONTAINER_MetaData | 210 | const struct GNUNET_CONTAINER_MetaData |
211 | *md2) | 211 | *md2) |
212 | { | 212 | { |
213 | struct MetaItem *i; | 213 | struct MetaItem *i; |
214 | struct MetaItem *j; | 214 | struct MetaItem *j; |
@@ -221,24 +221,24 @@ GNUNET_CONTAINER_meta_data_test_equal (const struct GNUNET_CONTAINER_MetaData | |||
221 | 221 | ||
222 | i = md1->items; | 222 | i = md1->items; |
223 | while (NULL != i) | 223 | while (NULL != i) |
224 | { | ||
225 | found = GNUNET_NO; | ||
226 | j = md2->items; | ||
227 | while (NULL != j) | ||
224 | { | 228 | { |
225 | found = GNUNET_NO; | 229 | if ((i->type == j->type) && (i->format == j->format) && |
226 | j = md2->items; | 230 | (i->data_size == j->data_size) && |
227 | while (NULL != j) | 231 | (0 == memcmp (i->data, j->data, i->data_size))) |
228 | { | 232 | { |
229 | if ((i->type == j->type) && (i->format == j->format) && | 233 | found = GNUNET_YES; |
230 | (i->data_size == j->data_size) && | 234 | break; |
231 | (0 == memcmp (i->data, j->data, i->data_size))) | 235 | } |
232 | { | 236 | j = j->next; |
233 | found = GNUNET_YES; | ||
234 | break; | ||
235 | } | ||
236 | j = j->next; | ||
237 | } | ||
238 | if (found == GNUNET_NO) | ||
239 | return GNUNET_NO; | ||
240 | i = i->next; | ||
241 | } | 237 | } |
238 | if (found == GNUNET_NO) | ||
239 | return GNUNET_NO; | ||
240 | i = i->next; | ||
241 | } | ||
242 | return GNUNET_YES; | 242 | return GNUNET_YES; |
243 | } | 243 | } |
244 | 244 | ||
@@ -263,11 +263,11 @@ GNUNET_CONTAINER_meta_data_test_equal (const struct GNUNET_CONTAINER_MetaData | |||
263 | */ | 263 | */ |
264 | int | 264 | int |
265 | GNUNET_CONTAINER_meta_data_insert (struct GNUNET_CONTAINER_MetaData *md, | 265 | GNUNET_CONTAINER_meta_data_insert (struct GNUNET_CONTAINER_MetaData *md, |
266 | const char *plugin_name, | 266 | const char *plugin_name, |
267 | enum EXTRACTOR_MetaType type, | 267 | enum EXTRACTOR_MetaType type, |
268 | enum EXTRACTOR_MetaFormat format, | 268 | enum EXTRACTOR_MetaFormat format, |
269 | const char *data_mime_type, | 269 | const char *data_mime_type, const char *data, |
270 | const char *data, size_t data_len) | 270 | size_t data_len) |
271 | { | 271 | { |
272 | struct MetaItem *prev; | 272 | struct MetaItem *prev; |
273 | struct MetaItem *pos; | 273 | struct MetaItem *pos; |
@@ -277,28 +277,28 @@ GNUNET_CONTAINER_meta_data_insert (struct GNUNET_CONTAINER_MetaData *md, | |||
277 | prev = NULL; | 277 | prev = NULL; |
278 | pos = md->items; | 278 | pos = md->items; |
279 | while (NULL != pos) | 279 | while (NULL != pos) |
280 | { | ||
281 | if (pos->data_size < data_len) | ||
282 | break; | ||
283 | if ((pos->type == type) && (pos->data_size == data_len) && | ||
284 | (0 == memcmp (pos->data, data, data_len))) | ||
280 | { | 285 | { |
281 | if (pos->data_size < data_len) | 286 | if ((pos->mime_type == NULL) && (data_mime_type != NULL)) |
282 | break; | 287 | { |
283 | if ((pos->type == type) && (pos->data_size == data_len) && | 288 | pos->mime_type = GNUNET_strdup (data_mime_type); |
284 | (0 == memcmp (pos->data, data, data_len))) | 289 | invalidate_sbuf (md); |
285 | { | 290 | } |
286 | if ((pos->mime_type == NULL) && (data_mime_type != NULL)) | 291 | if ((pos->format == EXTRACTOR_METAFORMAT_C_STRING) && |
287 | { | 292 | (format == EXTRACTOR_METAFORMAT_UTF8)) |
288 | pos->mime_type = GNUNET_strdup (data_mime_type); | 293 | { |
289 | invalidate_sbuf (md); | 294 | pos->format = EXTRACTOR_METAFORMAT_UTF8; |
290 | } | 295 | invalidate_sbuf (md); |
291 | if ((pos->format == EXTRACTOR_METAFORMAT_C_STRING) && | 296 | } |
292 | (format == EXTRACTOR_METAFORMAT_UTF8)) | 297 | return GNUNET_SYSERR; |
293 | { | ||
294 | pos->format = EXTRACTOR_METAFORMAT_UTF8; | ||
295 | invalidate_sbuf (md); | ||
296 | } | ||
297 | return GNUNET_SYSERR; | ||
298 | } | ||
299 | prev = pos; | ||
300 | pos = pos->next; | ||
301 | } | 298 | } |
299 | prev = pos; | ||
300 | pos = pos->next; | ||
301 | } | ||
302 | md->item_count++; | 302 | md->item_count++; |
303 | i = GNUNET_malloc (sizeof (struct MetaItem)); | 303 | i = GNUNET_malloc (sizeof (struct MetaItem)); |
304 | i->type = type; | 304 | i->type = type; |
@@ -310,23 +310,23 @@ GNUNET_CONTAINER_meta_data_insert (struct GNUNET_CONTAINER_MetaData *md, | |||
310 | else | 310 | else |
311 | prev->next = i; | 311 | prev->next = i; |
312 | i->mime_type = | 312 | i->mime_type = |
313 | (data_mime_type == NULL) ? NULL : GNUNET_strdup (data_mime_type); | 313 | (data_mime_type == NULL) ? NULL : GNUNET_strdup (data_mime_type); |
314 | i->plugin_name = (plugin_name == NULL) ? NULL : GNUNET_strdup (plugin_name); | 314 | i->plugin_name = (plugin_name == NULL) ? NULL : GNUNET_strdup (plugin_name); |
315 | i->data = GNUNET_malloc (data_len); | 315 | i->data = GNUNET_malloc (data_len); |
316 | memcpy (i->data, data, data_len); | 316 | memcpy (i->data, data, data_len); |
317 | /* change OS native dir separators to unix '/' and others to '_' */ | 317 | /* change OS native dir separators to unix '/' and others to '_' */ |
318 | 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)) | ||
319 | { | 322 | { |
320 | p = i->data; | 323 | if (*p == DIR_SEPARATOR) |
321 | while ((*p != '\0') && (p < i->data + data_len)) | 324 | *p = '/'; |
322 | { | 325 | else if (*p == '\\') |
323 | if (*p == DIR_SEPARATOR) | 326 | *p = '_'; |
324 | *p = '/'; | 327 | p++; |
325 | else if (*p == '\\') | ||
326 | *p = '_'; | ||
327 | p++; | ||
328 | } | ||
329 | } | 328 | } |
329 | } | ||
330 | invalidate_sbuf (md); | 330 | invalidate_sbuf (md); |
331 | return GNUNET_OK; | 331 | return GNUNET_OK; |
332 | } | 332 | } |
@@ -349,14 +349,14 @@ GNUNET_CONTAINER_meta_data_insert (struct GNUNET_CONTAINER_MetaData *md, | |||
349 | * @return 0 (to continue) | 349 | * @return 0 (to continue) |
350 | */ | 350 | */ |
351 | static int | 351 | static int |
352 | merge_helper (void *cls, const char *plugin_name, | 352 | merge_helper (void *cls, const char *plugin_name, enum EXTRACTOR_MetaType type, |
353 | enum EXTRACTOR_MetaType type, enum EXTRACTOR_MetaFormat format, | 353 | enum EXTRACTOR_MetaFormat format, const char *data_mime_type, |
354 | const char *data_mime_type, const char *data, size_t data_len) | 354 | const char *data, size_t data_len) |
355 | { | 355 | { |
356 | struct GNUNET_CONTAINER_MetaData *md = cls; | 356 | struct GNUNET_CONTAINER_MetaData *md = cls; |
357 | 357 | ||
358 | (void) GNUNET_CONTAINER_meta_data_insert (md, plugin_name, type, format, | 358 | (void) GNUNET_CONTAINER_meta_data_insert (md, plugin_name, type, format, |
359 | data_mime_type, data, data_len); | 359 | data_mime_type, data, data_len); |
360 | return 0; | 360 | return 0; |
361 | } | 361 | } |
362 | 362 | ||
@@ -370,7 +370,7 @@ merge_helper (void *cls, const char *plugin_name, | |||
370 | */ | 370 | */ |
371 | void | 371 | void |
372 | GNUNET_CONTAINER_meta_data_merge (struct GNUNET_CONTAINER_MetaData *md, | 372 | GNUNET_CONTAINER_meta_data_merge (struct GNUNET_CONTAINER_MetaData *md, |
373 | const struct GNUNET_CONTAINER_MetaData *in) | 373 | const struct GNUNET_CONTAINER_MetaData *in) |
374 | { | 374 | { |
375 | GNUNET_CONTAINER_meta_data_iterate (in, &merge_helper, md); | 375 | GNUNET_CONTAINER_meta_data_iterate (in, &merge_helper, md); |
376 | } | 376 | } |
@@ -388,8 +388,8 @@ GNUNET_CONTAINER_meta_data_merge (struct GNUNET_CONTAINER_MetaData *md, | |||
388 | */ | 388 | */ |
389 | int | 389 | int |
390 | GNUNET_CONTAINER_meta_data_delete (struct GNUNET_CONTAINER_MetaData *md, | 390 | GNUNET_CONTAINER_meta_data_delete (struct GNUNET_CONTAINER_MetaData *md, |
391 | enum EXTRACTOR_MetaType type, | 391 | enum EXTRACTOR_MetaType type, |
392 | const char *data, size_t data_len) | 392 | const char *data, size_t data_len) |
393 | { | 393 | { |
394 | struct MetaItem *pos; | 394 | struct MetaItem *pos; |
395 | struct MetaItem *prev; | 395 | struct MetaItem *prev; |
@@ -397,24 +397,24 @@ GNUNET_CONTAINER_meta_data_delete (struct GNUNET_CONTAINER_MetaData *md, | |||
397 | prev = NULL; | 397 | prev = NULL; |
398 | pos = md->items; | 398 | pos = md->items; |
399 | while (NULL != pos) | 399 | while (NULL != pos) |
400 | { | ||
401 | if ((pos->type == type) && | ||
402 | ((data == NULL) || | ||
403 | ((pos->data_size == data_len) && | ||
404 | (0 == memcmp (pos->data, data, data_len))))) | ||
400 | { | 405 | { |
401 | if ((pos->type == type) && | 406 | if (prev == NULL) |
402 | ((data == NULL) || | 407 | md->items = pos->next; |
403 | ((pos->data_size == data_len) && | 408 | else |
404 | (0 == memcmp (pos->data, data, data_len))))) | 409 | prev->next = pos->next; |
405 | { | 410 | meta_item_free (pos); |
406 | if (prev == NULL) | 411 | md->item_count--; |
407 | md->items = pos->next; | 412 | invalidate_sbuf (md); |
408 | else | 413 | return GNUNET_OK; |
409 | prev->next = pos->next; | ||
410 | meta_item_free (pos); | ||
411 | md->item_count--; | ||
412 | invalidate_sbuf (md); | ||
413 | return GNUNET_OK; | ||
414 | } | ||
415 | prev = pos; | ||
416 | pos = pos->next; | ||
417 | } | 414 | } |
415 | prev = pos; | ||
416 | pos = pos->next; | ||
417 | } | ||
418 | return GNUNET_SYSERR; | 418 | return GNUNET_SYSERR; |
419 | } | 419 | } |
420 | 420 | ||
@@ -427,20 +427,19 @@ GNUNET_CONTAINER_meta_data_delete (struct GNUNET_CONTAINER_MetaData *md, | |||
427 | */ | 427 | */ |
428 | void | 428 | void |
429 | GNUNET_CONTAINER_meta_data_add_publication_date (struct | 429 | GNUNET_CONTAINER_meta_data_add_publication_date (struct |
430 | GNUNET_CONTAINER_MetaData | 430 | GNUNET_CONTAINER_MetaData *md) |
431 | *md) | ||
432 | { | 431 | { |
433 | char *dat; | 432 | char *dat; |
434 | struct GNUNET_TIME_Absolute t; | 433 | struct GNUNET_TIME_Absolute t; |
435 | 434 | ||
436 | t = GNUNET_TIME_absolute_get (); | 435 | t = GNUNET_TIME_absolute_get (); |
437 | GNUNET_CONTAINER_meta_data_delete (md, EXTRACTOR_METATYPE_PUBLICATION_DATE, | 436 | GNUNET_CONTAINER_meta_data_delete (md, EXTRACTOR_METATYPE_PUBLICATION_DATE, |
438 | NULL, 0); | 437 | NULL, 0); |
439 | dat = GNUNET_STRINGS_absolute_time_to_string (t); | 438 | dat = GNUNET_STRINGS_absolute_time_to_string (t); |
440 | GNUNET_CONTAINER_meta_data_insert (md, "<gnunet>", | 439 | GNUNET_CONTAINER_meta_data_insert (md, "<gnunet>", |
441 | EXTRACTOR_METATYPE_PUBLICATION_DATE, | 440 | EXTRACTOR_METATYPE_PUBLICATION_DATE, |
442 | EXTRACTOR_METAFORMAT_UTF8, "text/plain", | 441 | EXTRACTOR_METAFORMAT_UTF8, "text/plain", |
443 | dat, strlen (dat) + 1); | 442 | dat, strlen (dat) + 1); |
444 | GNUNET_free (dat); | 443 | GNUNET_free (dat); |
445 | } | 444 | } |
446 | 445 | ||
@@ -454,9 +453,9 @@ GNUNET_CONTAINER_meta_data_add_publication_date (struct | |||
454 | * @return number of entries | 453 | * @return number of entries |
455 | */ | 454 | */ |
456 | int | 455 | int |
457 | GNUNET_CONTAINER_meta_data_iterate (const struct GNUNET_CONTAINER_MetaData | 456 | GNUNET_CONTAINER_meta_data_iterate (const struct GNUNET_CONTAINER_MetaData *md, |
458 | *md, EXTRACTOR_MetaDataProcessor iter, | 457 | EXTRACTOR_MetaDataProcessor iter, |
459 | void *iter_cls) | 458 | void *iter_cls) |
460 | { | 459 | { |
461 | struct MetaItem *pos; | 460 | struct MetaItem *pos; |
462 | 461 | ||
@@ -466,13 +465,13 @@ GNUNET_CONTAINER_meta_data_iterate (const struct GNUNET_CONTAINER_MetaData | |||
466 | return md->item_count; | 465 | return md->item_count; |
467 | pos = md->items; | 466 | pos = md->items; |
468 | while (NULL != pos) | 467 | while (NULL != pos) |
469 | { | 468 | { |
470 | if (0 != | 469 | if (0 != |
471 | iter (iter_cls, pos->plugin_name, pos->type, pos->format, | 470 | iter (iter_cls, pos->plugin_name, pos->type, pos->format, |
472 | pos->mime_type, pos->data, pos->data_size)) | 471 | pos->mime_type, pos->data, pos->data_size)) |
473 | return md->item_count; | 472 | return md->item_count; |
474 | pos = pos->next; | 473 | pos = pos->next; |
475 | } | 474 | } |
476 | return md->item_count; | 475 | return md->item_count; |
477 | } | 476 | } |
478 | 477 | ||
@@ -489,7 +488,7 @@ GNUNET_CONTAINER_meta_data_iterate (const struct GNUNET_CONTAINER_MetaData | |||
489 | */ | 488 | */ |
490 | char * | 489 | char * |
491 | GNUNET_CONTAINER_meta_data_get_by_type (const struct GNUNET_CONTAINER_MetaData | 490 | GNUNET_CONTAINER_meta_data_get_by_type (const struct GNUNET_CONTAINER_MetaData |
492 | *md, enum EXTRACTOR_MetaType type) | 491 | *md, enum EXTRACTOR_MetaType type) |
493 | { | 492 | { |
494 | struct MetaItem *pos; | 493 | struct MetaItem *pos; |
495 | 494 | ||
@@ -497,13 +496,13 @@ GNUNET_CONTAINER_meta_data_get_by_type (const struct GNUNET_CONTAINER_MetaData | |||
497 | return NULL; | 496 | return NULL; |
498 | pos = md->items; | 497 | pos = md->items; |
499 | while (NULL != pos) | 498 | while (NULL != pos) |
500 | { | 499 | { |
501 | if ((type == pos->type) && | 500 | if ((type == pos->type) && |
502 | ((pos->format == EXTRACTOR_METAFORMAT_UTF8) || | 501 | ((pos->format == EXTRACTOR_METAFORMAT_UTF8) || |
503 | (pos->format == EXTRACTOR_METAFORMAT_C_STRING))) | 502 | (pos->format == EXTRACTOR_METAFORMAT_C_STRING))) |
504 | return GNUNET_strdup (pos->data); | 503 | return GNUNET_strdup (pos->data); |
505 | pos = pos->next; | 504 | pos = pos->next; |
506 | } | 505 | } |
507 | return NULL; | 506 | return NULL; |
508 | } | 507 | } |
509 | 508 | ||
@@ -521,8 +520,8 @@ GNUNET_CONTAINER_meta_data_get_by_type (const struct GNUNET_CONTAINER_MetaData | |||
521 | */ | 520 | */ |
522 | char * | 521 | char * |
523 | GNUNET_CONTAINER_meta_data_get_first_by_types (const struct | 522 | GNUNET_CONTAINER_meta_data_get_first_by_types (const struct |
524 | GNUNET_CONTAINER_MetaData *md, | 523 | GNUNET_CONTAINER_MetaData *md, |
525 | ...) | 524 | ...) |
526 | { | 525 | { |
527 | char *ret; | 526 | char *ret; |
528 | va_list args; | 527 | va_list args; |
@@ -533,15 +532,15 @@ GNUNET_CONTAINER_meta_data_get_first_by_types (const struct | |||
533 | ret = NULL; | 532 | ret = NULL; |
534 | va_start (args, md); | 533 | va_start (args, md); |
535 | while (1) | 534 | while (1) |
536 | { | 535 | { |
537 | type = va_arg (args, enum EXTRACTOR_MetaType); | 536 | type = va_arg (args, enum EXTRACTOR_MetaType); |
538 | 537 | ||
539 | if (type == -1) | 538 | if (type == -1) |
540 | break; | 539 | break; |
541 | ret = GNUNET_CONTAINER_meta_data_get_by_type (md, type); | 540 | ret = GNUNET_CONTAINER_meta_data_get_by_type (md, type); |
542 | if (ret != NULL) | 541 | if (ret != NULL) |
543 | break; | 542 | break; |
544 | } | 543 | } |
545 | va_end (args); | 544 | va_end (args); |
546 | return ret; | 545 | return ret; |
547 | } | 546 | } |
@@ -556,9 +555,8 @@ GNUNET_CONTAINER_meta_data_get_first_by_types (const struct | |||
556 | * @return number of bytes in thumbnail, 0 if not available | 555 | * @return number of bytes in thumbnail, 0 if not available |
557 | */ | 556 | */ |
558 | size_t | 557 | size_t |
559 | GNUNET_CONTAINER_meta_data_get_thumbnail (const struct | 558 | GNUNET_CONTAINER_meta_data_get_thumbnail (const struct GNUNET_CONTAINER_MetaData |
560 | GNUNET_CONTAINER_MetaData * md, | 559 | * md, unsigned char **thumb) |
561 | unsigned char **thumb) | ||
562 | { | 560 | { |
563 | struct MetaItem *pos; | 561 | struct MetaItem *pos; |
564 | struct MetaItem *match; | 562 | struct MetaItem *match; |
@@ -568,19 +566,19 @@ GNUNET_CONTAINER_meta_data_get_thumbnail (const struct | |||
568 | match = NULL; | 566 | match = NULL; |
569 | pos = md->items; | 567 | pos = md->items; |
570 | while (NULL != pos) | 568 | while (NULL != pos) |
569 | { | ||
570 | if ((NULL != pos->mime_type) && | ||
571 | (0 == strncasecmp ("image/", pos->mime_type, strlen ("image/"))) && | ||
572 | (pos->format == EXTRACTOR_METAFORMAT_BINARY)) | ||
571 | { | 573 | { |
572 | if ((NULL != pos->mime_type) && | 574 | if (match == NULL) |
573 | (0 == strncasecmp ("image/", pos->mime_type, strlen ("image/"))) && | 575 | match = pos; |
574 | (pos->format == EXTRACTOR_METAFORMAT_BINARY)) | 576 | else if ((match->type != EXTRACTOR_METATYPE_THUMBNAIL) && |
575 | { | 577 | (pos->type == EXTRACTOR_METATYPE_THUMBNAIL)) |
576 | if (match == NULL) | 578 | match = pos; |
577 | match = pos; | ||
578 | else if ((match->type != EXTRACTOR_METATYPE_THUMBNAIL) && | ||
579 | (pos->type == EXTRACTOR_METATYPE_THUMBNAIL)) | ||
580 | match = pos; | ||
581 | } | ||
582 | pos = pos->next; | ||
583 | } | 579 | } |
580 | pos = pos->next; | ||
581 | } | ||
584 | if ((match == NULL) || (match->data_size == 0)) | 582 | if ((match == NULL) || (match->data_size == 0)) |
585 | return 0; | 583 | return 0; |
586 | *thumb = GNUNET_malloc (match->data_size); | 584 | *thumb = GNUNET_malloc (match->data_size); |
@@ -597,7 +595,7 @@ GNUNET_CONTAINER_meta_data_get_thumbnail (const struct | |||
597 | */ | 595 | */ |
598 | struct GNUNET_CONTAINER_MetaData * | 596 | struct GNUNET_CONTAINER_MetaData * |
599 | GNUNET_CONTAINER_meta_data_duplicate (const struct GNUNET_CONTAINER_MetaData | 597 | GNUNET_CONTAINER_meta_data_duplicate (const struct GNUNET_CONTAINER_MetaData |
600 | *md) | 598 | *md) |
601 | { | 599 | { |
602 | struct GNUNET_CONTAINER_MetaData *ret; | 600 | struct GNUNET_CONTAINER_MetaData *ret; |
603 | struct MetaItem *pos; | 601 | struct MetaItem *pos; |
@@ -607,12 +605,12 @@ GNUNET_CONTAINER_meta_data_duplicate (const struct GNUNET_CONTAINER_MetaData | |||
607 | ret = GNUNET_CONTAINER_meta_data_create (); | 605 | ret = GNUNET_CONTAINER_meta_data_create (); |
608 | pos = md->items; | 606 | pos = md->items; |
609 | while (NULL != pos) | 607 | while (NULL != pos) |
610 | { | 608 | { |
611 | GNUNET_CONTAINER_meta_data_insert (ret, pos->plugin_name, pos->type, | 609 | GNUNET_CONTAINER_meta_data_insert (ret, pos->plugin_name, pos->type, |
612 | pos->format, pos->mime_type, | 610 | pos->format, pos->mime_type, pos->data, |
613 | pos->data, pos->data_size); | 611 | pos->data_size); |
614 | pos = pos->next; | 612 | pos = pos->next; |
615 | } | 613 | } |
616 | return ret; | 614 | return ret; |
617 | } | 615 | } |
618 | 616 | ||
@@ -633,7 +631,7 @@ GNUNET_CONTAINER_meta_data_duplicate (const struct GNUNET_CONTAINER_MetaData | |||
633 | */ | 631 | */ |
634 | static int | 632 | static int |
635 | try_compression (const char *data, size_t oldSize, char **result, | 633 | try_compression (const char *data, size_t oldSize, char **result, |
636 | size_t * newSize) | 634 | size_t * newSize) |
637 | { | 635 | { |
638 | char *tmp; | 636 | char *tmp; |
639 | uLongf dlen; | 637 | uLongf dlen; |
@@ -648,14 +646,14 @@ try_compression (const char *data, size_t oldSize, char **result, | |||
648 | tmp = GNUNET_malloc (dlen); | 646 | tmp = GNUNET_malloc (dlen); |
649 | if (Z_OK == | 647 | if (Z_OK == |
650 | compress2 ((Bytef *) tmp, &dlen, (const Bytef *) data, oldSize, 9)) | 648 | compress2 ((Bytef *) tmp, &dlen, (const Bytef *) data, oldSize, 9)) |
649 | { | ||
650 | if (dlen < oldSize) | ||
651 | { | 651 | { |
652 | if (dlen < oldSize) | 652 | *result = tmp; |
653 | { | 653 | *newSize = dlen; |
654 | *result = tmp; | 654 | return GNUNET_YES; |
655 | *newSize = dlen; | ||
656 | return GNUNET_YES; | ||
657 | } | ||
658 | } | 655 | } |
656 | } | ||
659 | GNUNET_free (tmp); | 657 | GNUNET_free (tmp); |
660 | return GNUNET_NO; | 658 | return GNUNET_NO; |
661 | } | 659 | } |
@@ -756,10 +754,10 @@ struct MetaDataEntry | |||
756 | */ | 754 | */ |
757 | ssize_t | 755 | ssize_t |
758 | GNUNET_CONTAINER_meta_data_serialize (const struct GNUNET_CONTAINER_MetaData | 756 | GNUNET_CONTAINER_meta_data_serialize (const struct GNUNET_CONTAINER_MetaData |
759 | *md, char **target, size_t max, | 757 | *md, char **target, size_t max, |
760 | enum | 758 | enum |
761 | GNUNET_CONTAINER_MetaDataSerializationOptions | 759 | GNUNET_CONTAINER_MetaDataSerializationOptions |
762 | opt) | 760 | opt) |
763 | { | 761 | { |
764 | struct GNUNET_CONTAINER_MetaData *vmd; | 762 | struct GNUNET_CONTAINER_MetaData *vmd; |
765 | struct MetaItem *pos; | 763 | struct MetaItem *pos; |
@@ -781,79 +779,79 @@ GNUNET_CONTAINER_meta_data_serialize (const struct GNUNET_CONTAINER_MetaData | |||
781 | int comp; | 779 | int comp; |
782 | 780 | ||
783 | if (max < sizeof (struct MetaDataHeader)) | 781 | if (max < sizeof (struct MetaDataHeader)) |
784 | return GNUNET_SYSERR; /* far too small */ | 782 | return GNUNET_SYSERR; /* far too small */ |
785 | if (md == NULL) | 783 | if (md == NULL) |
786 | return 0; | 784 | return 0; |
787 | 785 | ||
788 | if (md->sbuf != NULL) | 786 | if (md->sbuf != NULL) |
787 | { | ||
788 | /* try to use serialization cache */ | ||
789 | if (md->sbuf_size <= max) | ||
789 | { | 790 | { |
790 | /* try to use serialization cache */ | 791 | if (NULL == *target) |
791 | if (md->sbuf_size <= max) | 792 | *target = GNUNET_malloc (md->sbuf_size); |
792 | { | 793 | memcpy (*target, md->sbuf, md->sbuf_size); |
793 | if (NULL == *target) | 794 | return md->sbuf_size; |
794 | *target = GNUNET_malloc (md->sbuf_size); | ||
795 | memcpy (*target, md->sbuf, md->sbuf_size); | ||
796 | return md->sbuf_size; | ||
797 | } | ||
798 | if (0 == (opt & GNUNET_CONTAINER_META_DATA_SERIALIZE_PART)) | ||
799 | return GNUNET_SYSERR; /* can say that this will fail */ | ||
800 | /* need to compute a partial serialization, sbuf useless ... */ | ||
801 | } | 795 | } |
796 | if (0 == (opt & GNUNET_CONTAINER_META_DATA_SERIALIZE_PART)) | ||
797 | return GNUNET_SYSERR; /* can say that this will fail */ | ||
798 | /* need to compute a partial serialization, sbuf useless ... */ | ||
799 | } | ||
802 | dst = NULL; | 800 | dst = NULL; |
803 | msize = 0; | 801 | msize = 0; |
804 | pos = md->items; | 802 | pos = md->items; |
805 | while (NULL != pos) | 803 | while (NULL != pos) |
806 | { | 804 | { |
807 | msize += sizeof (struct MetaDataEntry); | 805 | msize += sizeof (struct MetaDataEntry); |
808 | msize += pos->data_size; | 806 | msize += pos->data_size; |
809 | if (pos->plugin_name != NULL) | 807 | if (pos->plugin_name != NULL) |
810 | msize += strlen (pos->plugin_name) + 1; | 808 | msize += strlen (pos->plugin_name) + 1; |
811 | if (pos->mime_type != NULL) | 809 | if (pos->mime_type != NULL) |
812 | msize += strlen (pos->mime_type) + 1; | 810 | msize += strlen (pos->mime_type) + 1; |
813 | pos = pos->next; | 811 | pos = pos->next; |
814 | } | 812 | } |
815 | size = (size_t) msize; | 813 | size = (size_t) msize; |
816 | if (size != msize) | 814 | if (size != msize) |
817 | { | 815 | { |
818 | GNUNET_break (0); /* integer overflow */ | 816 | GNUNET_break (0); /* integer overflow */ |
819 | return GNUNET_SYSERR; | 817 | return GNUNET_SYSERR; |
820 | } | 818 | } |
821 | if (size >= GNUNET_MAX_MALLOC_CHECKED) | 819 | if (size >= GNUNET_MAX_MALLOC_CHECKED) |
822 | { | 820 | { |
823 | /* too large to be processed */ | 821 | /* too large to be processed */ |
824 | return GNUNET_SYSERR; | 822 | return GNUNET_SYSERR; |
825 | } | 823 | } |
826 | ent = GNUNET_malloc (size); | 824 | ent = GNUNET_malloc (size); |
827 | mdata = (char *) &ent[md->item_count]; | 825 | mdata = (char *) &ent[md->item_count]; |
828 | off = size - (md->item_count * sizeof (struct MetaDataEntry)); | 826 | off = size - (md->item_count * sizeof (struct MetaDataEntry)); |
829 | i = 0; | 827 | i = 0; |
830 | pos = md->items; | 828 | pos = md->items; |
831 | while (NULL != pos) | 829 | while (NULL != pos) |
832 | { | 830 | { |
833 | ent[i].type = htonl ((uint32_t) pos->type); | 831 | ent[i].type = htonl ((uint32_t) pos->type); |
834 | ent[i].format = htonl ((uint32_t) pos->format); | 832 | ent[i].format = htonl ((uint32_t) pos->format); |
835 | ent[i].data_size = htonl ((uint32_t) pos->data_size); | 833 | ent[i].data_size = htonl ((uint32_t) pos->data_size); |
836 | if (pos->plugin_name == NULL) | 834 | if (pos->plugin_name == NULL) |
837 | plen = 0; | 835 | plen = 0; |
838 | else | 836 | else |
839 | plen = strlen (pos->plugin_name) + 1; | 837 | plen = strlen (pos->plugin_name) + 1; |
840 | ent[i].plugin_name_len = htonl ((uint32_t) plen); | 838 | ent[i].plugin_name_len = htonl ((uint32_t) plen); |
841 | if (pos->mime_type == NULL) | 839 | if (pos->mime_type == NULL) |
842 | mlen = 0; | 840 | mlen = 0; |
843 | else | 841 | else |
844 | mlen = strlen (pos->mime_type) + 1; | 842 | mlen = strlen (pos->mime_type) + 1; |
845 | ent[i].mime_type_len = htonl ((uint32_t) mlen); | 843 | ent[i].mime_type_len = htonl ((uint32_t) mlen); |
846 | off -= pos->data_size; | 844 | off -= pos->data_size; |
847 | memcpy (&mdata[off], pos->data, pos->data_size); | 845 | memcpy (&mdata[off], pos->data, pos->data_size); |
848 | off -= plen; | 846 | off -= plen; |
849 | if (pos->plugin_name != NULL) | 847 | if (pos->plugin_name != NULL) |
850 | memcpy (&mdata[off], pos->plugin_name, plen); | 848 | memcpy (&mdata[off], pos->plugin_name, plen); |
851 | off -= mlen; | 849 | off -= mlen; |
852 | if (pos->mime_type != NULL) | 850 | if (pos->mime_type != NULL) |
853 | memcpy (&mdata[off], pos->mime_type, mlen); | 851 | memcpy (&mdata[off], pos->mime_type, mlen); |
854 | i++; | 852 | i++; |
855 | pos = pos->next; | 853 | pos = pos->next; |
856 | } | 854 | } |
857 | GNUNET_assert (off == 0); | 855 | GNUNET_assert (off == 0); |
858 | 856 | ||
859 | clen = 0; | 857 | clen = 0; |
@@ -862,95 +860,95 @@ GNUNET_CONTAINER_meta_data_serialize (const struct GNUNET_CONTAINER_MetaData | |||
862 | i = 0; | 860 | i = 0; |
863 | pos = md->items; | 861 | pos = md->items; |
864 | while (pos != NULL) | 862 | while (pos != NULL) |
863 | { | ||
864 | comp = GNUNET_NO; | ||
865 | if (0 == (opt & GNUNET_CONTAINER_META_DATA_SERIALIZE_NO_COMPRESS)) | ||
866 | comp = try_compression ((const char *) &ent[i], left, &cdata, &clen); | ||
867 | |||
868 | if ((md->sbuf == NULL) && (i == 0)) | ||
869 | { | ||
870 | /* fill 'sbuf'; this "modifies" md, but since this is only | ||
871 | * an internal cache we will cast away the 'const' instead | ||
872 | * of making the API look strange. */ | ||
873 | vmd = (struct GNUNET_CONTAINER_MetaData *) md; | ||
874 | hdr = GNUNET_malloc (left + sizeof (struct MetaDataHeader)); | ||
875 | hdr->size = htonl (left); | ||
876 | hdr->entries = htonl (md->item_count); | ||
877 | if (GNUNET_YES == comp) | ||
878 | { | ||
879 | GNUNET_assert (clen < left); | ||
880 | hdr->version = htonl (2 | HEADER_COMPRESSED); | ||
881 | memcpy (&hdr[1], cdata, clen); | ||
882 | vmd->sbuf_size = clen + sizeof (struct MetaDataHeader); | ||
883 | } | ||
884 | else | ||
885 | { | ||
886 | hdr->version = htonl (2); | ||
887 | memcpy (&hdr[1], &ent[0], left); | ||
888 | vmd->sbuf_size = left + sizeof (struct MetaDataHeader); | ||
889 | } | ||
890 | vmd->sbuf = (char *) hdr; | ||
891 | } | ||
892 | |||
893 | if (((left + sizeof (struct MetaDataHeader)) <= max) || | ||
894 | ((comp == GNUNET_YES) && (clen <= max))) | ||
895 | { | ||
896 | /* success, this now fits! */ | ||
897 | if (GNUNET_YES == comp) | ||
898 | { | ||
899 | if (dst == NULL) | ||
900 | dst = GNUNET_malloc (clen + sizeof (struct MetaDataHeader)); | ||
901 | hdr = (struct MetaDataHeader *) dst; | ||
902 | hdr->version = htonl (2 | HEADER_COMPRESSED); | ||
903 | hdr->size = htonl (left); | ||
904 | hdr->entries = htonl (md->item_count - i); | ||
905 | memcpy (&dst[sizeof (struct MetaDataHeader)], cdata, clen); | ||
906 | GNUNET_free (cdata); | ||
907 | GNUNET_free (ent); | ||
908 | rlen = clen + sizeof (struct MetaDataHeader); | ||
909 | } | ||
910 | else | ||
911 | { | ||
912 | if (dst == NULL) | ||
913 | dst = GNUNET_malloc (left + sizeof (struct MetaDataHeader)); | ||
914 | hdr = (struct MetaDataHeader *) dst; | ||
915 | hdr->version = htonl (2); | ||
916 | hdr->entries = htonl (md->item_count - i); | ||
917 | hdr->size = htonl (left); | ||
918 | memcpy (&dst[sizeof (struct MetaDataHeader)], &ent[i], left); | ||
919 | GNUNET_free (ent); | ||
920 | rlen = left + sizeof (struct MetaDataHeader); | ||
921 | } | ||
922 | if (NULL != *target) | ||
923 | { | ||
924 | memcpy (*target, dst, clen + sizeof (struct MetaDataHeader)); | ||
925 | GNUNET_free (dst); | ||
926 | } | ||
927 | else | ||
928 | { | ||
929 | *target = dst; | ||
930 | } | ||
931 | return rlen; | ||
932 | } | ||
933 | |||
934 | if (0 == (opt & GNUNET_CONTAINER_META_DATA_SERIALIZE_PART)) | ||
865 | { | 935 | { |
866 | comp = GNUNET_NO; | 936 | /* does not fit! */ |
867 | if (0 == (opt & GNUNET_CONTAINER_META_DATA_SERIALIZE_NO_COMPRESS)) | 937 | GNUNET_free (ent); |
868 | comp = try_compression ((const char *) &ent[i], left, &cdata, &clen); | 938 | return GNUNET_SYSERR; |
869 | |||
870 | if ((md->sbuf == NULL) && (i == 0)) | ||
871 | { | ||
872 | /* fill 'sbuf'; this "modifies" md, but since this is only | ||
873 | * an internal cache we will cast away the 'const' instead | ||
874 | * of making the API look strange. */ | ||
875 | vmd = (struct GNUNET_CONTAINER_MetaData *) md; | ||
876 | hdr = GNUNET_malloc (left + sizeof (struct MetaDataHeader)); | ||
877 | hdr->size = htonl (left); | ||
878 | hdr->entries = htonl (md->item_count); | ||
879 | if (GNUNET_YES == comp) | ||
880 | { | ||
881 | GNUNET_assert (clen < left); | ||
882 | hdr->version = htonl (2 | HEADER_COMPRESSED); | ||
883 | memcpy (&hdr[1], cdata, clen); | ||
884 | vmd->sbuf_size = clen + sizeof (struct MetaDataHeader); | ||
885 | } | ||
886 | else | ||
887 | { | ||
888 | hdr->version = htonl (2); | ||
889 | memcpy (&hdr[1], &ent[0], left); | ||
890 | vmd->sbuf_size = left + sizeof (struct MetaDataHeader); | ||
891 | } | ||
892 | vmd->sbuf = (char *) hdr; | ||
893 | } | ||
894 | |||
895 | if (((left + sizeof (struct MetaDataHeader)) <= max) || | ||
896 | ((comp == GNUNET_YES) && (clen <= max))) | ||
897 | { | ||
898 | /* success, this now fits! */ | ||
899 | if (GNUNET_YES == comp) | ||
900 | { | ||
901 | if (dst == NULL) | ||
902 | dst = GNUNET_malloc (clen + sizeof (struct MetaDataHeader)); | ||
903 | hdr = (struct MetaDataHeader *) dst; | ||
904 | hdr->version = htonl (2 | HEADER_COMPRESSED); | ||
905 | hdr->size = htonl (left); | ||
906 | hdr->entries = htonl (md->item_count - i); | ||
907 | memcpy (&dst[sizeof (struct MetaDataHeader)], cdata, clen); | ||
908 | GNUNET_free (cdata); | ||
909 | GNUNET_free (ent); | ||
910 | rlen = clen + sizeof (struct MetaDataHeader); | ||
911 | } | ||
912 | else | ||
913 | { | ||
914 | if (dst == NULL) | ||
915 | dst = GNUNET_malloc (left + sizeof (struct MetaDataHeader)); | ||
916 | hdr = (struct MetaDataHeader *) dst; | ||
917 | hdr->version = htonl (2); | ||
918 | hdr->entries = htonl (md->item_count - i); | ||
919 | hdr->size = htonl (left); | ||
920 | memcpy (&dst[sizeof (struct MetaDataHeader)], &ent[i], left); | ||
921 | GNUNET_free (ent); | ||
922 | rlen = left + sizeof (struct MetaDataHeader); | ||
923 | } | ||
924 | if (NULL != *target) | ||
925 | { | ||
926 | memcpy (*target, dst, clen + sizeof (struct MetaDataHeader)); | ||
927 | GNUNET_free (dst); | ||
928 | } | ||
929 | else | ||
930 | { | ||
931 | *target = dst; | ||
932 | } | ||
933 | return rlen; | ||
934 | } | ||
935 | |||
936 | if (0 == (opt & GNUNET_CONTAINER_META_DATA_SERIALIZE_PART)) | ||
937 | { | ||
938 | /* does not fit! */ | ||
939 | GNUNET_free (ent); | ||
940 | return GNUNET_SYSERR; | ||
941 | } | ||
942 | |||
943 | /* next iteration: ignore the corresponding meta data at the | ||
944 | * end and try again without it */ | ||
945 | left -= sizeof (struct MetaDataEntry); | ||
946 | left -= pos->data_size; | ||
947 | if (pos->plugin_name != NULL) | ||
948 | left -= strlen (pos->plugin_name) + 1; | ||
949 | if (pos->mime_type != NULL) | ||
950 | left -= strlen (pos->mime_type) + 1; | ||
951 | pos = pos->next; | ||
952 | i++; | ||
953 | } | 939 | } |
940 | |||
941 | /* next iteration: ignore the corresponding meta data at the | ||
942 | * end and try again without it */ | ||
943 | left -= sizeof (struct MetaDataEntry); | ||
944 | left -= pos->data_size; | ||
945 | if (pos->plugin_name != NULL) | ||
946 | left -= strlen (pos->plugin_name) + 1; | ||
947 | if (pos->mime_type != NULL) | ||
948 | left -= strlen (pos->mime_type) + 1; | ||
949 | pos = pos->next; | ||
950 | i++; | ||
951 | } | ||
954 | GNUNET_free (ent); | 952 | GNUNET_free (ent); |
955 | 953 | ||
956 | /* nothing fit, only write header! */ | 954 | /* nothing fit, only write header! */ |
@@ -972,7 +970,7 @@ GNUNET_CONTAINER_meta_data_serialize (const struct GNUNET_CONTAINER_MetaData | |||
972 | */ | 970 | */ |
973 | ssize_t | 971 | ssize_t |
974 | GNUNET_CONTAINER_meta_data_get_serialized_size (const struct | 972 | GNUNET_CONTAINER_meta_data_get_serialized_size (const struct |
975 | GNUNET_CONTAINER_MetaData *md) | 973 | GNUNET_CONTAINER_MetaData *md) |
976 | { | 974 | { |
977 | ssize_t ret; | 975 | ssize_t ret; |
978 | char *ptr; | 976 | char *ptr; |
@@ -981,8 +979,8 @@ GNUNET_CONTAINER_meta_data_get_serialized_size (const struct | |||
981 | return md->sbuf_size; | 979 | return md->sbuf_size; |
982 | ptr = NULL; | 980 | ptr = NULL; |
983 | ret = | 981 | ret = |
984 | GNUNET_CONTAINER_meta_data_serialize (md, &ptr, GNUNET_MAX_MALLOC_CHECKED, | 982 | GNUNET_CONTAINER_meta_data_serialize (md, &ptr, GNUNET_MAX_MALLOC_CHECKED, |
985 | GNUNET_CONTAINER_META_DATA_SERIALIZE_FULL); | 983 | GNUNET_CONTAINER_META_DATA_SERIALIZE_FULL); |
986 | if (ret != -1) | 984 | if (ret != -1) |
987 | GNUNET_free (ptr); | 985 | GNUNET_free (ptr); |
988 | return ret; | 986 | return ret; |
@@ -1009,14 +1007,14 @@ decompress (const char *input, size_t inputSize, size_t outputSize) | |||
1009 | output = GNUNET_malloc (olen); | 1007 | output = GNUNET_malloc (olen); |
1010 | if (Z_OK == | 1008 | if (Z_OK == |
1011 | uncompress ((Bytef *) output, &olen, (const Bytef *) input, inputSize)) | 1009 | uncompress ((Bytef *) output, &olen, (const Bytef *) input, inputSize)) |
1012 | { | 1010 | { |
1013 | return output; | 1011 | return output; |
1014 | } | 1012 | } |
1015 | else | 1013 | else |
1016 | { | 1014 | { |
1017 | GNUNET_free (output); | 1015 | GNUNET_free (output); |
1018 | return NULL; | 1016 | return NULL; |
1019 | } | 1017 | } |
1020 | } | 1018 | } |
1021 | 1019 | ||
1022 | 1020 | ||
@@ -1058,121 +1056,121 @@ GNUNET_CONTAINER_meta_data_deserialize (const char *input, size_t size) | |||
1058 | compressed = (ntohl (hdr.version) & HEADER_COMPRESSED) != 0; | 1056 | compressed = (ntohl (hdr.version) & HEADER_COMPRESSED) != 0; |
1059 | 1057 | ||
1060 | if (version == 1) | 1058 | if (version == 1) |
1061 | return NULL; /* null pointer */ | 1059 | return NULL; /* null pointer */ |
1062 | if (version != 2) | 1060 | if (version != 2) |
1063 | { | 1061 | { |
1064 | GNUNET_break_op (0); /* unsupported version */ | 1062 | GNUNET_break_op (0); /* unsupported version */ |
1065 | return NULL; | 1063 | return NULL; |
1066 | } | 1064 | } |
1067 | 1065 | ||
1068 | ic = ntohl (hdr.entries); | 1066 | ic = ntohl (hdr.entries); |
1069 | dataSize = ntohl (hdr.size); | 1067 | dataSize = ntohl (hdr.size); |
1070 | if ((sizeof (struct MetaDataEntry) * ic) > dataSize) | 1068 | if ((sizeof (struct MetaDataEntry) * ic) > dataSize) |
1069 | { | ||
1070 | GNUNET_break_op (0); | ||
1071 | return NULL; | ||
1072 | } | ||
1073 | |||
1074 | if (compressed) | ||
1075 | { | ||
1076 | if (dataSize >= GNUNET_MAX_MALLOC_CHECKED) | ||
1071 | { | 1077 | { |
1078 | /* make sure we don't blow our memory limit because of a mal-formed | ||
1079 | * message... */ | ||
1072 | GNUNET_break_op (0); | 1080 | GNUNET_break_op (0); |
1073 | return NULL; | 1081 | return NULL; |
1074 | } | 1082 | } |
1075 | 1083 | data = | |
1076 | if (compressed) | 1084 | decompress ((const char *) &input[sizeof (struct MetaDataHeader)], |
1085 | size - sizeof (struct MetaDataHeader), dataSize); | ||
1086 | if (data == NULL) | ||
1077 | { | 1087 | { |
1078 | if (dataSize >= GNUNET_MAX_MALLOC_CHECKED) | 1088 | GNUNET_break_op (0); |
1079 | { | 1089 | return NULL; |
1080 | /* make sure we don't blow our memory limit because of a mal-formed | ||
1081 | * message... */ | ||
1082 | GNUNET_break_op (0); | ||
1083 | return NULL; | ||
1084 | } | ||
1085 | data = | ||
1086 | decompress ((const char *) &input[sizeof (struct MetaDataHeader)], | ||
1087 | size - sizeof (struct MetaDataHeader), dataSize); | ||
1088 | if (data == NULL) | ||
1089 | { | ||
1090 | GNUNET_break_op (0); | ||
1091 | return NULL; | ||
1092 | } | ||
1093 | cdata = data; | ||
1094 | } | 1090 | } |
1091 | cdata = data; | ||
1092 | } | ||
1095 | else | 1093 | else |
1094 | { | ||
1095 | data = NULL; | ||
1096 | cdata = (const char *) &input[sizeof (struct MetaDataHeader)]; | ||
1097 | if (dataSize != size - sizeof (struct MetaDataHeader)) | ||
1096 | { | 1098 | { |
1097 | data = NULL; | 1099 | GNUNET_break_op (0); |
1098 | cdata = (const char *) &input[sizeof (struct MetaDataHeader)]; | 1100 | return NULL; |
1099 | if (dataSize != size - sizeof (struct MetaDataHeader)) | ||
1100 | { | ||
1101 | GNUNET_break_op (0); | ||
1102 | return NULL; | ||
1103 | } | ||
1104 | } | 1101 | } |
1102 | } | ||
1105 | 1103 | ||
1106 | md = GNUNET_CONTAINER_meta_data_create (); | 1104 | md = GNUNET_CONTAINER_meta_data_create (); |
1107 | left = dataSize - ic * sizeof (struct MetaDataEntry); | 1105 | left = dataSize - ic * sizeof (struct MetaDataEntry); |
1108 | mdata = &cdata[ic * sizeof (struct MetaDataEntry)]; | 1106 | mdata = &cdata[ic * sizeof (struct MetaDataEntry)]; |
1109 | for (i = 0; i < ic; i++) | 1107 | for (i = 0; i < ic; i++) |
1108 | { | ||
1109 | memcpy (&ent, &cdata[i * sizeof (struct MetaDataEntry)], | ||
1110 | sizeof (struct MetaDataEntry)); | ||
1111 | format = (enum EXTRACTOR_MetaFormat) ntohl (ent.format); | ||
1112 | if ((format != EXTRACTOR_METAFORMAT_UTF8) && | ||
1113 | (format != EXTRACTOR_METAFORMAT_C_STRING) && | ||
1114 | (format != EXTRACTOR_METAFORMAT_BINARY)) | ||
1110 | { | 1115 | { |
1111 | memcpy (&ent, &cdata[i * sizeof (struct MetaDataEntry)], | 1116 | GNUNET_break_op (0); |
1112 | sizeof (struct MetaDataEntry)); | 1117 | break; |
1113 | format = (enum EXTRACTOR_MetaFormat) ntohl (ent.format); | 1118 | } |
1114 | if ((format != EXTRACTOR_METAFORMAT_UTF8) && | 1119 | dlen = ntohl (ent.data_size); |
1115 | (format != EXTRACTOR_METAFORMAT_C_STRING) && | 1120 | plen = ntohl (ent.plugin_name_len); |
1116 | (format != EXTRACTOR_METAFORMAT_BINARY)) | 1121 | mlen = ntohl (ent.mime_type_len); |
1117 | { | 1122 | if (dlen > left) |
1118 | GNUNET_break_op (0); | 1123 | { |
1119 | break; | 1124 | GNUNET_break_op (0); |
1120 | } | 1125 | break; |
1121 | dlen = ntohl (ent.data_size); | 1126 | } |
1122 | plen = ntohl (ent.plugin_name_len); | 1127 | left -= dlen; |
1123 | mlen = ntohl (ent.mime_type_len); | 1128 | meta_data = &mdata[left]; |
1124 | if (dlen > left) | 1129 | if ((format == EXTRACTOR_METAFORMAT_UTF8) || |
1125 | { | 1130 | (format == EXTRACTOR_METAFORMAT_C_STRING)) |
1126 | GNUNET_break_op (0); | 1131 | { |
1127 | break; | 1132 | if ((dlen == 0) || (mdata[left + dlen - 1] != '\0')) |
1128 | } | 1133 | { |
1129 | left -= dlen; | 1134 | GNUNET_break_op (0); |
1130 | meta_data = &mdata[left]; | 1135 | break; |
1131 | if ((format == EXTRACTOR_METAFORMAT_UTF8) || | 1136 | } |
1132 | (format == EXTRACTOR_METAFORMAT_C_STRING)) | 1137 | } |
1133 | { | 1138 | if (plen > left) |
1134 | if ((dlen == 0) || (mdata[left + dlen - 1] != '\0')) | 1139 | { |
1135 | { | 1140 | GNUNET_break_op (0); |
1136 | GNUNET_break_op (0); | 1141 | break; |
1137 | break; | 1142 | } |
1138 | } | 1143 | left -= plen; |
1139 | } | 1144 | if ((plen > 0) && (mdata[left + plen - 1] != '\0')) |
1140 | if (plen > left) | 1145 | { |
1141 | { | 1146 | GNUNET_break_op (0); |
1142 | GNUNET_break_op (0); | 1147 | break; |
1143 | break; | 1148 | } |
1144 | } | 1149 | if (plen == 0) |
1145 | left -= plen; | 1150 | plugin_name = NULL; |
1146 | if ((plen > 0) && (mdata[left + plen - 1] != '\0')) | 1151 | else |
1147 | { | 1152 | plugin_name = &mdata[left]; |
1148 | GNUNET_break_op (0); | 1153 | |
1149 | break; | 1154 | if (mlen > left) |
1150 | } | 1155 | { |
1151 | if (plen == 0) | 1156 | GNUNET_break_op (0); |
1152 | plugin_name = NULL; | 1157 | break; |
1153 | else | 1158 | } |
1154 | plugin_name = &mdata[left]; | 1159 | left -= mlen; |
1155 | 1160 | if ((mlen > 0) && (mdata[left + mlen - 1] != '\0')) | |
1156 | if (mlen > left) | 1161 | { |
1157 | { | 1162 | GNUNET_break_op (0); |
1158 | GNUNET_break_op (0); | 1163 | break; |
1159 | break; | ||
1160 | } | ||
1161 | left -= mlen; | ||
1162 | if ((mlen > 0) && (mdata[left + mlen - 1] != '\0')) | ||
1163 | { | ||
1164 | GNUNET_break_op (0); | ||
1165 | break; | ||
1166 | } | ||
1167 | if (mlen == 0) | ||
1168 | mime_type = NULL; | ||
1169 | else | ||
1170 | mime_type = &mdata[left]; | ||
1171 | GNUNET_CONTAINER_meta_data_insert (md, plugin_name, | ||
1172 | (enum EXTRACTOR_MetaType) | ||
1173 | ntohl (ent.type), format, mime_type, | ||
1174 | meta_data, dlen); | ||
1175 | } | 1164 | } |
1165 | if (mlen == 0) | ||
1166 | mime_type = NULL; | ||
1167 | else | ||
1168 | mime_type = &mdata[left]; | ||
1169 | GNUNET_CONTAINER_meta_data_insert (md, plugin_name, | ||
1170 | (enum EXTRACTOR_MetaType) | ||
1171 | ntohl (ent.type), format, mime_type, | ||
1172 | meta_data, dlen); | ||
1173 | } | ||
1176 | GNUNET_free_non_null (data); | 1174 | GNUNET_free_non_null (data); |
1177 | return md; | 1175 | return md; |
1178 | } | 1176 | } |