aboutsummaryrefslogtreecommitdiff
path: root/gnu/gnunet/metadata.scm
diff options
context:
space:
mode:
authorMaxime Devos <maximedevos@telenet.be>2021-01-04 19:38:20 +0100
committerMaxime Devos <maximedevos@telenet.be>2021-09-21 12:08:27 +0200
commit61b013c733aaaca2723ab6af5cdf441dec53ab1f (patch)
treef1c2fc59ab5944088804b900b350bb5590a30928 /gnu/gnunet/metadata.scm
parent643cb8be6ea2bf7930340df128650945b5292967 (diff)
downloadgnunet-scheme-61b013c733aaaca2723ab6af5cdf441dec53ab1f.tar.gz
gnunet-scheme-61b013c733aaaca2723ab6af5cdf441dec53ab1f.zip
remove some uses of old accessors
The newer ones are harder to use incorrectly, and perform some validation.
Diffstat (limited to 'gnu/gnunet/metadata.scm')
-rw-r--r--gnu/gnunet/metadata.scm397
1 files changed, 164 insertions, 233 deletions
diff --git a/gnu/gnunet/metadata.scm b/gnu/gnunet/metadata.scm
index 2152c71..b870dcd 100644
--- a/gnu/gnunet/metadata.scm
+++ b/gnu/gnunet/metadata.scm
@@ -51,6 +51,9 @@
51 (only (gnu extractor metatypes) 51 (only (gnu extractor metatypes)
52 integer->meta-type 52 integer->meta-type
53 meta-type?) 53 meta-type?)
54 (gnu gnunet utils netstruct)
55 (gnu gnunet utils bv-slice)
56 (gnu gnunet metadata struct)
54 (only (gnu gnunet utils decompress) decompress) 57 (only (gnu gnunet utils decompress) decompress)
55 (only (gnu gnunet utils hat-let) let^) 58 (only (gnu gnunet utils hat-let) let^)
56 (only (srfi srfi-31) rec) 59 (only (srfi srfi-31) rec)
@@ -216,56 +219,6 @@ meta data) name of extracting plugin
216 new-item))))) 219 new-item)))))
217 (else (loop (+ 1 i))))))) 220 (else (loop (+ 1 i)))))))
218 221
219 ;; Header for serialized meta data
220 (define sizeof-MetaDataHeader 4)
221
222 (define (MetaDataHeader.version bv offset)
223 "The version of the MD serialization. The highest bit is used to
224indicate compression.
225
226Version 0 is traditional (pre-0.9) meta data (unsupported)
227Version is 1 for a NULL pointer
228Version 2 is for 0.9.x (and possibly higher)
229Other version numbers are not yet defined."
230 (bytevector-u32-ref bv offset (endianness big)))
231
232 (define (MetaDataHeader.entries bv offset)
233 "How many MD entries are there?"
234 (bytevector-u32-ref bv (+ offset 4) (endianness big)))
235
236 (define (MetaDataHeader.size bv offset)
237 "Size of the decompressed meta data"
238 (bytevector-u32-ref bv (+ offset 8) (endianness big)))
239 ;; This is followed by 'entries' values of type 'struct MetaDataEntry'
240 ;; and then by 'entry' plugin names, mime-types and data blocks
241 ;; as specified in those meta data entries.
242
243 ;; Entry of serialized meta data.
244 (define sizeof-MetaDataEntry 20)
245
246 (define (MetaDataEntry.type bv offset)
247 "Meta data type. Corresponds to a @code{<meta-type>}"
248 (integer->meta-type (bytevector-u32-ref bv offset (endianness big))))
249
250 (define (MetaDataEntry.format bv offset)
251 "Meta data format. Corresponds to a @code{<meta-format>}"
252 (integer->meta-format
253 (bytevector-u32-ref bv (+ offset 4) (endianness big))))
254
255 (define (MetaDataEntry.data-size bv offset)
256 "Number of bytes of meta data."
257 (bytevector-u32-ref bv (+ offset 8) (endianness big)))
258
259 (define (MetaDataEntry.plugin-name-length bv offset)
260 "Number of bytes in the plugin name including 0-terminator.
2610 for NULL."
262 (bytevector-u32-ref bv (+ offset 12) (endianness big)))
263
264 (define (MetaDataEntry.mime-type-length bv offset)
265 "Number of bytes in the mime type including 0-terminator.
2660 for NULL."
267 (bytevector-u32-ref bv (+ offset 16) (endianness big)))
268
269 (define (vector-insert vec i x) 222 (define (vector-insert vec i x)
270 "Insert @var{x} into the vector @var{vec} at offset @var{i}" 223 "Insert @var{x} into the vector @var{vec} at offset @var{i}"
271 (vector-unfold (lambda (j) 224 (vector-unfold (lambda (j)
@@ -287,149 +240,141 @@ Other version numbers are not yet defined."
287 (bytevector-copy! bv offset bv-new 0 length) 240 (bytevector-copy! bv offset bv-new 0 length)
288 bv-new)) 241 bv-new))
289 242
290 ;; TODO: bytevector slices 243 (define (meta-data-deserialize slice)
291 (define meta-data-deserialize 244 "Deserialize meta-data, as a <meta-data>.
292 (case-lambda
293 "Deserialize meta-data, as a <meta-data>.
294 245
295The serialized meta-data is passed as a bytevector 246The serialized meta-data is passed as a readable slice @var{slice}.
296@var{bv}, starting at offset @var{offset} and of byte-length 247In case of success, return an appropriate @code{<meta-data>}.
297@var{size}. In case of success, return an appropriate 248In case of a parsing error, return @code{#f}.
298@code{<meta-data>}. In case of a parsing error, return @code{#f}.
299(Unsupported versions count as parsing errors.) 249(Unsupported versions count as parsing errors.)
300 250
301TODO: perhaps a variant raising conditions may be more informative." 251TODO: perhaps a variant raising conditions may be more informative."
302 ((bv) (meta-data-deserialize bv 0 (bytevector-length bv))) 252 ;; Argument checks
303 ((bv offset size) 253 (let^ ((!! (slice? slice))
304 ;; Argument checks 254 (!! (slice-readable? slice))
305 (let^ ((!! (bytevector? bv)) 255 ;; Header checks
306 (!! (and (integer? offset) (exact? offset))) 256 (? (< (size-length slice) (sizeof MetaDataHeader ())) #f)
307 (!! (and (integer? size) (exact? size))) 257 (! header (slice-slice slice 0 (sizeof MetaDataHeader ())))
308 (!! (and (<= 0 offset) (<= offset (bytevector-length bv)))) 258 (! version (bitwise-and (read% MetaDataHeader ("version") header)
309 (!! (and (<= 0 size) 259 HEADER_VERSION_MASK))
310 (<= (+ offset size) (bytevector-length bv)))) 260 (? (not (= 2 version)) #f) ; unsupported version
311 ;; Header checks 261 (! ic (read% MetaDataHeader ("entries") header))
312 (? (< size sizeof-MetaDataHeader) #f) 262 (! data-size (read% MetaDataHeader ("size") header))
313 (! version (bitwise-and (MetaDataHeader.version bv offset) 263 (? (or (> (* ic (sizeof MetaDataEntry ())) data-size)
314 HEADER_VERSION_MASK)) 264 (and (not (= 0 ic))
315 (? (not (= 2 version)) #f) ; unsupported version 265 ;; TODO: isn't this clause redundant?
316 (! ic (MetaDataHeader.entries bv offset)) 266 (< data-size
317 (! data-size (MetaDataHeader.size bv offset)) 267 (* ic (sizeof MetaDataEntry ())))))
318 (? (or (> (* ic sizeof-MetaDataEntry) data-size) 268 #f)
319 (and (not (= 0 ic)) 269 ;; Decompression
320 ;; TODO: isn't this clause redundant? 270 (! compressed?
321 (< data-size 271 (not (= 0 (bitwise-and
322 (* ic sizeof-MetaDataEntry)))) 272 (read% MetaDataHeader ("version") header)))))
323 #f) 273 (! cdata
324 ;; Decompression 274 (let ((maybe-compressed
325 (! compressed? 275 (slice-slice slice (sizeof MetaDataHeader ()))))
326 (not (= 0 (bitwise-and (MetaDataHeader.version bv offset))))) 276 (cond ((not compressed?)
327 (<- (cdata-bv cdata-offset) 277 maybe-compressed)
328 (cond ((not compressed?) 278 ((>= data-size GNUNET_MAX_MALLOC_CHECKED)
329 (values bv (+ offset sizeof-MetaDataHeader))) 279 ;; make sure we don't blow our memory limit because
330 ((>= data-size GNUNET_MAX_MALLOC_CHECKED) 280 ;; of a mal-formed message... 40 MiB seems rather
331 ;; make sure we don't blow our memory limit because 281 ;; large to encounter in the wild, so this
332 ;; of a mal-formed message... 40 MiB seems rather 282 ;; is unlikely to be a problem.
333 ;; large to encounter in the wild, so this 283 #f)
334 ;; is unlikely to be a problem. 284 (else
335 #f) 285 (decompress maybe-compressed data-size)))))
336 (else 286 ;; Check decompression was successful
337 (values 287 (? (not cdata) #f)
338 (decompress bv 288 (! mdata (slice-slice cdata (* ic (sizeof MetaDataEntry ()))))
339 (+ offset sizeof-MetaDataHeader) 289 ;; Loop over metadata
340 data-size) 290 (/o/ loop-metadata
341 0)))) 291 (i 0)
342 ;; Check decompression was successful 292 (md (make-meta-data))
343 (? (not cdata-bv) #f) 293 (left (- data-size (* ic (sizeof MetaDataEntry ())))))
344 (! mdata-offset (+ cdata-offset 294 (? (>= i ic) md) ;; all metadata is deserialised
345 (* ic sizeof-MetaDataEntry))) 295 (! from-entry-till-end
346 ;; Loop over metadata 296 (slice-slice cdata (* ic (sizeof MetaDataEntry ()))))
347 (/o/ loop-metadata 297 (! entry-header
348 (i 0) 298 (slice-slice from-entry-till-end
349 (md (make-meta-data)) 299 0 (sizeof MetaDataEntry)))
350 (left (- data-size (* ic sizeof-MetaDataEntry)))) 300 (! format (read% MetaDataEntry ("format") entry-header))
351 (? (>= i ic) md) ;; all metadata is deserialised 301 ;; Bail out if the metaformat is unrecognised
352 (! entry-offset 302 ;; FIXME why did I write 0 here?
353 (+ cdata-offset (* ic sizeof-MetaDataEntry))) 303 (? (not (member 0 `(,METAFORMAT_UTF8 ,METAFORMAT_C_STRING
354 (! format (MetaDataEntry.format bv entry-offset)) 304 ,METAFORMAT_BINARY)))
355 ;; Bail out if the metaformat is unrecognised 305 ;; TODO: upstream returns incomplete @var{md}
356 (? (not (member 0 `(,METAFORMAT_UTF8 ,METAFORMAT_C_STRING 306 ;; in this case! Return NULL instead!
357 ,METAFORMAT_BINARY))) 307 ;; (An incomplete @var{md} is returned in
358 ;; TODO: upstream returns incomplete @var{md} 308 ;; some other cases as well.)
359 ;; in this case! Return NULL instead! 309 #f)
360 ;; (An incomplete @var{md} is returned in 310 (! entry-data-length
361 ;; some other cases as well.) 311 (read% MetaDataEntry ("data-size") entry-header))
362 #f) 312 (! plugin-name-length
363 (! entry-data-length 313 (read% MetaDataEntry ("plugin-name-length") entry-header))
364 (MetaDataEntry.data-size cdata-bv entry-offset)) 314 (! mime-type-length
365 (! plugin-name-length 315 (read% MetaDataEntry ("mime-type-length") entry-header))
366 (MetaDataEntry.plugin-name-length cdata-bv 316 (? (> entry-data-length left) #f)
367 entry-offset)) 317 (! left (- left entry-data-length))
368 (! mime-type-length 318 (! meta-data-offset
369 (MetaDataEntry.mime-type-length cdata-bv 319 (+ mdata-offset left))
370 entry-offset)) 320 ;; Strings are terminated with a \0
371 (? (> entry-data-length left) #f) 321 ;; TODO: upstream doesn't check the location of
372 (! left (- left entry-data-length)) 322 ;; the **first** \0. Is this intentional or irrelevant?
373 (! meta-data-offset 323 (? (and (member format
374 (+ mdata-offset left)) 324 `(,METAFORMAT_UTF8 ,METAFORMAT_C_STRING))
375 ;; Strings are terminated with a \0 325 (or (= 0 entry-data-length)
376 ;; TODO: upstream doesn't check the location of 326 (not (= (bytevector-u8-ref
377 ;; the **first** \0. Is this intentional or irrelevant? 327 cdata-bv
378 (? (and (member format 328 (+ meta-data-offset
379 `(,METAFORMAT_UTF8 ,METAFORMAT_C_STRING)) 329 (- entry-data-length 1)))))))
380 (or (= 0 entry-data-length) 330 #f)
381 (not (= (bytevector-u8-ref 331 (? (> plugin-name-length left) #f)
382 cdata-bv 332 (! left (- left plugin-name-length))
383 (+ meta-data-offset 333 (? (and (> plugin-name-length 0)
384 (- entry-data-length 1))))))) 334 (not (= 0 (bytevector-u8-ref
385 #f) 335 cdata-bv
386 (? (> plugin-name-length left) #f) 336 (+ mdata-offset
387 (! left (- left plugin-name-length)) 337 left
388 (? (and (> plugin-name-length 0) 338 plugin-name-length
389 (not (= 0 (bytevector-u8-ref 339 -1)))))
390 cdata-bv 340 #f)
391 (+ mdata-offset 341 ;; FIXME plen or entry-data-length
392 left 342 ;; Does not include terminating \0.
393 plugin-name-length 343 (! plugin-bv
394 -1))))) 344 (and (> plugin-name-length 0)
395 #f) 345 (bv-slice cdata-bv (+ mdata-offset left)
396 ;; FIXME plen or entry-data-length 346 (- plugin-name-length 1))))
397 ;; Does not include terminating \0. 347 ;; There isn't any formal requirement for
398 (! plugin-bv 348 ;; being encoded as UTF-8 as far as I know,
399 (and (> plugin-name-length 0) 349 ;; but in practice this will probably be ASCII,
400 (bv-slice cdata-bv (+ mdata-offset left) 350 ;; which is a subset of UTF-8.
401 (- plugin-name-length 1)))) 351 (! plugin-string
402 ;; There isn't any formal requirement for 352 (and plugin-bv (utf8->string plugin-bv)))
403 ;; being encoded as UTF-8 as far as I know, 353 (? (> mime-type-length left) #f)
404 ;; but in practice this will probably be ASCII, 354 (! left (- left mime-type-length))
405 ;; which is a subset of UTF-8. 355 (? (and (> mime-type-length 0)
406 (! plugin-string 356 (< 0 (bytevector-u8-ref cdata-bv
407 (and plugin-bv (utf8->string plugin-bv))) 357 (+ mdata-offset
408 (? (> mime-type-length left) #f) 358 mime-type-length
409 (! left (- left mime-type-length)) 359 -1))))
410 (? (and (> mime-type-length 0) 360 #f)
411 (< 0 (bytevector-u8-ref cdata-bv 361 (! mime-type-string
412 (+ mdata-offset 362 (and (< 0 mime-type-length)
413 mime-type-length 363 (utf8->string (bv-slice cdata-bv
414 -1)))) 364 (+ mdata-offset
415 #f) 365 left -1)
416 (! mime-type-string 366 (- mime-type-length 1)))))
417 (and (< 0 mime-type-length) 367 (! new-md
418 (utf8->string (bv-slice cdata-bv 368 (meta-data-extend
419 (+ mdata-offset 369 md plugin-string
420 left -1) 370 (read% MetaDataEntry ("type") entry)
421 (- mime-type-length 1))))) 371 format
422 (! new-md 372 mime-type-string
423 (meta-data-extend 373 (bv-slice cdata-bv meta-data-offset
424 md plugin-string 374 entry-data-length))))
425 (MetaDataEntry.type cdata-bv entry-offset) 375 (loop-metadata (+ i 1)
426 format 376 new-md
427 mime-type-string 377 left)))
428 (bv-slice cdata-bv meta-data-offset
429 entry-data-length))))
430 (loop-metadata (+ i 1)
431 new-md
432 left)))))
433 378
434 (define (break) 379 (define (break)
435 "This state seems rather suspicious, but not necessarily incorrect." 380 "This state seems rather suspicious, but not necessarily incorrect."
@@ -455,7 +400,7 @@ of the metadata acceptable)"
455 (let^ ((! size 400 (let^ ((! size
456 (vector-fold 401 (vector-fold
457 (lambda (m) 402 (lambda (m)
458 (+ sizeof-MetaDataEntry 403 (+ (sizeof MetaDataEntry ())
459 (meta-item-data-size m) 404 (meta-item-data-size m)
460 ;; Is ASCII, therefore 405 ;; Is ASCII, therefore
461 ;; string length and 406 ;; string length and
@@ -474,47 +419,34 @@ of the metadata acceptable)"
474 #f) 419 #f)
475 (! ent-bv (make-bytevector size)) 420 (! ent-bv (make-bytevector size))
476 (! mdata-offset 421 (! mdata-offset
477 (* sizeof-MetaDataEntry 422 (* (sizeof MetaDataEntry ())
478 (meta-data-item-count meta-data))) 423 (meta-data-item-count meta-data)))
479 (_ (let^ ((/o/ meta-item-loop 424 (_ (let^ ((/o/ meta-item-loop
480 (i 0) 425 (i 0)
481 (off (- size 426 (off (- size
482 (* sizeof-MetaDataEntry 427 (* (sizeof MetaDataEntry ())
483 (meta-data-item-count meta-data))))) 428 (meta-data-item-count meta-data)))))
484 (? (>= i (meta-data-item-count meta-data)) 429 (? (>= i (meta-data-item-count meta-data))
485 (assert (= 0 off)) 430 (assert (= 0 off))
486 'done) 431 'done)
487 (! item (vector-ref (meta-data-items meta-data) i)) 432 (! item (vector-ref (meta-data-items meta-data) i))
488 (! ent-offset (* i sizeof-MetaDataEntry)) 433 (! ent-offset (* i (sizeof MetaDataEntry ())))
489 (_ (set-MetaDataEntry.type! 434 (_ (set%! MetaDataEntry (type) ent-slice (meta-item-type item)))
490 ent-bv 435 (_ (set%! MetaDataEntry (format) ent-slice (meta-item-format item)))
491 ent-offset 436 (_ (set%! MetaDataEntry (data-size) ent-slice (meta-item-data-size item)))
492 (meta-item-type item)))
493 (_ (set-MetaDataEntry.format!
494 ent-bv
495 ent-offset
496 (meta-item-format item)))
497 (_ (set-MetaDataEntry.data-size!
498 ent-bv
499 ent-offset
500 (meta-item-data-size item)))
501 (! pname (meta-item-plugin-name item)) 437 (! pname (meta-item-plugin-name item))
502 (! mime (meta-item-mime-type item)) 438 (! mime (meta-item-mime-type item))
503 (! plugin-bv (and pname (string->utf8 pname))) 439 (! plugin-bv (and pname (string->utf8 pname)))
504 (! mime-bv (and mime (string->utf8 mime))) 440 (! mime-bv (and mime (string->utf8 mime)))
505 ;; Add 1 byte for terminating \0. 441 ;; Add 1 byte for terminating \0.
506 (_ (set-MetaDataEntry.plugin-name-length 442 (_ (set%! MetaDataEntry ("plugin-name-length") ent
507 ent-bv 443 (if plugin-bv
508 ent-offset 444 (1+ (bytevector-length plugin-bv))
509 (if plugin-bv 445 0)))
510 (+ 1 (bytevector-length plugin-bv)) 446 (_ (set%! MetaDataEntry ("mime-type-length") ent
511 0))) 447 (if mime-bv
512 (_ (set-MetaDataEntry.mime-type-length 448 (+ 1 (bytevector-length mime-bv))
513 ent-bv 449 0)))
514 ent-offset
515 (if mime-bv
516 (+ 1 (bytevector-length mime-bv))
517 0)))
518 (! off (- off (meta-item-data-size item))) 450 (! off (- off (meta-item-data-size item)))
519 ;; Check for \0 bytes 451 ;; Check for \0 bytes
520 ;; TODO: perform this check elsewhere 452 ;; TODO: perform this check elsewhere
@@ -573,14 +505,15 @@ of the metadata acceptable)"
573 (! i 0) 505 (! i 0)
574 (? (>= i (meta-data-item-count meta-data)) 506 (? (>= i (meta-data-item-count meta-data))
575 ;; No meta data, only write header 507 ;; No meta data, only write header
576 (let^ ((! result-bv (make-bytevector sizeof-MetaDataHeader)) 508 (let^ ((! result (make-slice/read-write
577 (_ (set-MetaDataHeader.version! result-bv 0 2)) 509 (sizeof MetaDataHeader ())))
578 (_ (set-MetaDataHeader.entries! result-bv 0 0)) 510 (_ (set%! MetaDataHeader (version) result 2))
579 (_ (set-MetaDataHeader.size! result-bv 0 0))) 511 (_ (set%! MetaDataHeader (entries) result 0))
512 (_ (set%! MetaDataHeader (size!) result 0 0)))
580 result-bv)) 513 result-bv))
581 (! left size) 514 (! left size)
582 (! ent-offset 515 (! ent-offset
583 (+ (* i sizeof-MetaDataEntry))) 516 (+ (* i (sizeof MetaDataEntry ()))))
584 ;; TODO in upstream, it is possible to request 517 ;; TODO in upstream, it is possible to request
585 ;; no compression 518 ;; no compression
586 (! cdata (try-compression ent-bv ent-offset left)) 519 (! cdata (try-compression ent-bv ent-offset left))
@@ -588,21 +521,19 @@ of the metadata acceptable)"
588 (if cdata 521 (if cdata
589 (bytevector-length cdata) 522 (bytevector-length cdata)
590 left)) 523 left))
591 (! hdr (make-bytevector (+ sizeof-MetaDataHeader 524 (! hdr (make-bytevector (+ (sizeof MetaDataHeader ())
592 maybe-compessed-length))) 525 maybe-compessed-length)))
593 ;; TODO proper #f or condition on overflow 526 ;; TODO proper #f or condition on overflow
594 (_ (set-MetaDataHeader.size! hdr 0 left)) 527 (_ (set%! MetaDataHeader (size) hdr left))
595 (_ (set-MetaDataHeader.entries! 528 (_ (set%! MetaDataHeader (entries) hdr
596 hdr 0 (meta-data-item-count meta-data))) 529 (meta-data-item-count meta-data)))
597 (!! (==> cdata (< (bytevector-length cdata) left))) 530 (!! (==> cdata (< (bytevector-length cdata) left)))
598 (_ (set-MetaDataHeader.version! hdr 0 531 (_ (set%! MetaDataHeader (version hdr)
599 (bitwise-ior 532 (bitwise-ior 2 (if cdata
600 2 533 HEADER_COMPRESSED
601 (if cdata 534 0))))
602 HEADER_COMPRESSED
603 0))))
604 (_ (bytevector-copy! (or cdata ent-bv) 535 (_ (bytevector-copy! (or cdata ent-bv)
605 (if cdata 0 ent-offset) 536 (if cdata 0 ent-offset)
606 hdr sizeof-MetaDataHeader 537 hdr (sizeof MetaDataHeader ())
607 maybe-compressed-length))) 538 maybe-compressed-length)))
608 hdr))) 539 hdr)))