From 5a99d3a380f5e4388de91fe466e56566ecccd651 Mon Sep 17 00:00:00 2001 From: Matthew Butterick Date: Thu, 10 Aug 2017 16:10:01 -0700 Subject: [PATCH] improve some errors --- pitfall/xenomorph/private/pointer.rkt | 3 +++ pitfall/xenomorph/private/string.rkt | 8 +++++++- pitfall/xenomorph/private/struct.rkt | 8 +++++--- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/pitfall/xenomorph/private/pointer.rkt b/pitfall/xenomorph/private/pointer.rkt index ba6d258a..35753a49 100644 --- a/pitfall/xenomorph/private/pointer.rkt +++ b/pitfall/xenomorph/private/pointer.rkt @@ -71,6 +71,9 @@ https://github.com/mbutterick/restructure/blob/master/src/Pointer.coffee (define/augment (encode port val [ctx #f]) + (unless ctx + ;; todo: furnish default pointer context? adapt from Struct? + (raise-argument-error 'Pointer:encode "valid pointer context" ctx)) (if (not val) (send offset-type encode port null-value) (let* ([parent ctx] diff --git a/pitfall/xenomorph/private/string.rkt b/pitfall/xenomorph/private/string.rkt index 8ad56856..1166390c 100644 --- a/pitfall/xenomorph/private/string.rkt +++ b/pitfall/xenomorph/private/string.rkt @@ -57,8 +57,11 @@ https://github.com/mbutterick/restructure/blob/master/src/String.coffee [encoding (if (procedure? encoding) (or (encoding (and parent (· parent val)) 'ascii)) encoding)]) + (define encoded-length (byte-length val encoding)) + (when (and (exact-nonnegative-integer? len) (> encoded-length len)) + (raise-argument-error 'String:encode (format "string no longer than ~a" len) val)) (when (NumberT? len) - (send len encode port (byte-length val encoding))) + (send len encode port encoded-length)) (write-encoded-string port val encoding) (when (not len) (write-byte #x00 port)))) ; null terminated when no len @@ -89,6 +92,9 @@ https://github.com/mbutterick/restructure/blob/master/src/String.coffee (test-module + (define S-fixed (+String 4 'utf8)) + (check-equal? (encode S-fixed "Mike" #f) #"Mike") + (check-exn exn:fail? (λ () (encode S-fixed "Mikes" #f))) ; too long for fixed string (define S (+String uint8 'utf8)) (check-equal? (decode S #"\2BCDEF") "BC") (check-equal? (encode S "Mike" #f) #"\4Mike") diff --git a/pitfall/xenomorph/private/struct.rkt b/pitfall/xenomorph/private/struct.rkt index bc8d0402..b9a2ac35 100644 --- a/pitfall/xenomorph/private/struct.rkt +++ b/pitfall/xenomorph/private/struct.rkt @@ -114,6 +114,11 @@ https://github.com/mbutterick/restructure/blob/master/src/Struct.coffee (unless (dict? val) (raise-argument-error 'Struct:encode "dict" val)) + ;; check keys first, since `size` also relies on keys being valid + (unless (andmap (λ (key) (memq key (dict-keys val))) (dict-keys fields)) + (raise-argument-error 'Struct:encode + (format "dict that contains superset of Struct keys: ~a" (dict-keys fields)) (dict-keys val))) + (define ctx (mhash 'pointers empty 'startOffset (pos port) 'parent parent @@ -121,9 +126,6 @@ https://github.com/mbutterick/restructure/blob/master/src/Struct.coffee 'pointerSize 0)) (ref-set! ctx 'pointerOffset (+ (pos port) (size val ctx #f))) - (unless (andmap (λ (key) (memq key (dict-keys val))) (dict-keys fields)) - (raise-argument-error 'Struct:encode - (format "dict that contains superset of Struct keys: ~a" (dict-keys fields)) (dict-keys val))) (for ([(key type) (in-dict fields)]) (send type encode port (ref val key) ctx)) (for ([ptr (in-list (· ctx pointers))])