diff --git a/dataformats.c b/dataformats.c index feb4a69e..7789ed0c 100644 --- a/dataformats.c +++ b/dataformats.c @@ -32,27 +32,38 @@ int cmp_sid_t(const sid_t *a, const sid_t *b) int str_to_sid_t(sid_t *sidp, const char *hex) { - const char *end; - return strn_to_sid_t(sidp, hex, SIZE_MAX, &end) != -1 && *end == '\0' ? 0 : -1; + return parse_sid_t(sidp, hex, -1, NULL); // checks for nul terminator } -int strn_to_sid_t(sid_t *sidp, const char *hex, size_t hexlen, const char **endp) +int strn_to_sid_t(sid_t *sidp, const char *hex, size_t hexlen) { - if (strn_startswith(hex, hexlen, "broadcast", endp)) { + return parse_sid_t(sidp, hex, hexlen, NULL); // does not check for nul terminator +} + +int parse_sid_t(sid_t *sidp, const char *hex, ssize_t hexlen, const char **endp) +{ + const char *end = NULL; + if (strn_startswith(hex, hexlen, "broadcast", &end)) { + if (endp) + *endp = end; + else if (hexlen == -1 && *end != '\0') + return -1; if (sidp) *sidp = SID_BROADCAST; return 0; } - sid_t tmp; - if (hexlen < sizeof tmp.binary * 2) + if (hexlen != -1 && hexlen != SID_STRLEN) return -1; + sid_t tmp; int n = fromhex(tmp.binary, hex, sizeof tmp.binary); if (n != sizeof tmp.binary) return -1; + if (endp) + *endp = hex + SID_STRLEN; + else if (hexlen == -1 && hex[SID_STRLEN] != '\0') + return -1; if (sidp) *sidp = tmp; - if (endp) - *endp = hex + sizeof tmp.binary * 2; return 0; } @@ -84,19 +95,28 @@ int cmp_rhizome_bid_t(const rhizome_bid_t *a, const rhizome_bid_t *b) int str_to_rhizome_bid_t(rhizome_bid_t *bid, const char *hex) { - return bid ? fromhexstr(bid->binary, hex, sizeof bid->binary) : is_xstring(hex, RHIZOME_BUNDLE_ID_STRLEN) ? 0 : -1; + return parse_rhizome_bid_t(bid, hex, -1, NULL); // checks for nul terminator } -int strn_to_rhizome_bid_t(rhizome_bid_t *bid, const char *hex, const char **endp) +int strn_to_rhizome_bid_t(rhizome_bid_t *bid, const char *hex, size_t hexlen) { + return parse_rhizome_bid_t(bid, hex, hexlen, NULL); // does not check for nul terminator +} + +int parse_rhizome_bid_t(rhizome_bid_t *bid, const char *hex, ssize_t hexlen, const char **endp) +{ + if (hexlen != -1 && hexlen != RHIZOME_BUNDLE_ID_STRLEN) + return -1; rhizome_bid_t tmp; int n = fromhex(tmp.binary, hex, sizeof tmp.binary); if (n != sizeof tmp.binary) return -1; + if (endp) + *endp = hex + RHIZOME_BUNDLE_ID_STRLEN; + else if (hexlen == -1 && hex[RHIZOME_BUNDLE_ID_STRLEN] != '\0') + return -1; if (bid) *bid = tmp; - if (endp) - *endp = hex + sizeof tmp.binary * 2; return 0; } @@ -107,37 +127,55 @@ int cmp_rhizome_filehash_t(const rhizome_filehash_t *a, const rhizome_filehash_t int str_to_rhizome_filehash_t(rhizome_filehash_t *hashp, const char *hex) { - return hashp ? fromhexstr(hashp->binary, hex, sizeof hashp->binary) : is_xstring(hex, RHIZOME_FILEHASH_STRLEN) ? 0 : -1; + return parse_rhizome_filehash_t(hashp, hex, -1, NULL); // checks for nul terminator } -int strn_to_rhizome_filehash_t(rhizome_filehash_t *hashp, const char *hex, const char **endp) +int strn_to_rhizome_filehash_t(rhizome_filehash_t *hashp, const char *hex, size_t hexlen) { + return parse_rhizome_filehash_t(hashp, hex, hexlen, NULL); // does not check for nul terminator +} + +int parse_rhizome_filehash_t(rhizome_filehash_t *hashp, const char *hex, ssize_t hexlen, const char **endp) +{ + if (hexlen != -1 && hexlen != RHIZOME_FILEHASH_STRLEN) + return -1; rhizome_filehash_t tmp; int n = fromhex(tmp.binary, hex, sizeof tmp.binary); if (n != sizeof tmp.binary) return -1; + if (endp) + *endp = hex + RHIZOME_FILEHASH_STRLEN; + else if (hexlen == -1 && hex[RHIZOME_FILEHASH_STRLEN] != '\0') + return -1; if (hashp) *hashp = tmp; - if (endp) - *endp = hex + sizeof tmp.binary * 2; return 0; } int str_to_rhizome_bk_t(rhizome_bk_t *bkp, const char *hex) { - return bkp ? fromhexstr(bkp->binary, hex, sizeof bkp->binary) : is_xstring(hex, RHIZOME_BUNDLE_KEY_STRLEN) ? 0 : -1; + return parse_rhizome_bk_t(bkp, hex, -1, NULL); // checks for nul terminator } -int strn_to_rhizome_bk_t(rhizome_bk_t *bkp, const char *hex, const char **endp) +int strn_to_rhizome_bk_t(rhizome_bk_t *bkp, const char *hex, size_t hexlen) { + return parse_rhizome_bk_t(bkp, hex, hexlen, NULL); // does not check for nul terminator +} + +int parse_rhizome_bk_t(rhizome_bk_t *bkp, const char *hex, ssize_t hexlen, const char **endp) +{ + if (hexlen != -1 && hexlen != RHIZOME_BUNDLE_KEY_STRLEN) + return -1; rhizome_bk_t tmp; int n = fromhex(tmp.binary, hex, sizeof tmp.binary); if (n != sizeof tmp.binary) return -1; + if (endp) + *endp = hex + RHIZOME_BUNDLE_KEY_STRLEN; + else if (hexlen == -1 && hex[RHIZOME_BUNDLE_KEY_STRLEN] != '\0') + return -1; if (bkp) *bkp = tmp; - if (endp) - *endp = hex + sizeof tmp.binary * 2; return 0; } @@ -157,7 +195,7 @@ int strn_to_rhizome_bsk_t(rhizome_bk_t *bskp, const char *text, size_t textlen) strn_digest_passphrase(bskp->binary, sizeof bskp->binary, text, textlen); return 0; } - return strn_to_rhizome_bk_t(bskp, text, NULL); + return strn_to_rhizome_bk_t(bskp, text, textlen); } int rhizome_strn_is_bundle_crypt_key(const char *key) diff --git a/mdp_filter.c b/mdp_filter.c index 8245cb13..ad6a7ddc 100644 --- a/mdp_filter.c +++ b/mdp_filter.c @@ -452,7 +452,7 @@ static int _endpoint(Cursor c, uint8_t *flagsp, uint8_t port_flag, struct subscr preload(c, SID_STRLEN); if (skip(c, "*")) { *subscr = NULL; - } else if (strn_to_sid_t(&sid, preloaded(c), available(c), &end) == 0) { + } else if (parse_sid_t(&sid, preloaded(c), available(c), &end) == 0) { if ((*subscr = find_subscriber(sid.binary, sizeof sid.binary, 1)) == NULL) return 0; advance_to(c, end); diff --git a/meshms_restful.c b/meshms_restful.c index 970925d7..9c04325e 100644 --- a/meshms_restful.c +++ b/meshms_restful.c @@ -124,7 +124,7 @@ int restful_meshms_(httpd_request *r, const char *remainder) http_size_t content_length = CONTENT_LENGTH_UNKNOWN; HTTP_HANDLER *handler = NULL; const char *end; - if (strn_to_sid_t(&r->sid1, remainder, SIZE_MAX, &end) != -1) { + if (parse_sid_t(&r->sid1, remainder, -1, &end) != -1) { remainder = end; if (strcmp(remainder, "/conversationlist.json") == 0) { handler = restful_meshms_conversationlist_json; @@ -136,7 +136,7 @@ int restful_meshms_(httpd_request *r, const char *remainder) content_length = 0; remainder = ""; } - else if (*remainder == '/' && strn_to_sid_t(&r->sid2, remainder + 1, SIZE_MAX, &end) != -1) { + else if (*remainder == '/' && parse_sid_t(&r->sid2, remainder + 1, -1, &end) != -1) { remainder = end; if (strcmp(remainder, "/messagelist.json") == 0) { handler = restful_meshms_messagelist_json; diff --git a/rhizome_bundle.c b/rhizome_bundle.c index 3a2b35d0..61ccbdf6 100644 --- a/rhizome_bundle.c +++ b/rhizome_bundle.c @@ -524,7 +524,7 @@ int rhizome_manifest_inspect(const char *buf, size_t len, struct rhizome_manifes eol = p; if (has_bid == 1) { const char *e; - if (strn_to_rhizome_bid_t(&summ->bid, begin, &e) == 0 && e == eol) + if (parse_rhizome_bid_t(&summ->bid, begin, eol - begin, &e) == 0 && e == eol) has_bid = 2; else state = Error; // invalid "id" field diff --git a/rhizome_restful.c b/rhizome_restful.c index 3820979e..bb8a34e2 100644 --- a/rhizome_restful.c +++ b/rhizome_restful.c @@ -559,7 +559,7 @@ static int insert_mime_part_end(struct http_request *hr) httpd_request *r = (httpd_request *) hr; if (r->u.insert.current_part == PART_AUTHOR) { if ( r->u.insert.author_hex_len != sizeof r->u.insert.author_hex - || strn_to_sid_t(&r->u.insert.author, r->u.insert.author_hex, sizeof r->u.insert.author_hex, NULL) == -1 + || strn_to_sid_t(&r->u.insert.author, r->u.insert.author_hex, sizeof r->u.insert.author_hex) == -1 ) return http_response_form_part(r, "Invalid", PART_AUTHOR, r->u.insert.author_hex, r->u.insert.author_hex_len); r->u.insert.received_author = 1; @@ -738,7 +738,7 @@ int restful_rhizome_(httpd_request *r, const char *remainder) HTTP_HANDLER *handler = NULL; rhizome_bid_t bid; const char *end; - if (strn_to_rhizome_bid_t(&bid, remainder, &end) != -1) { + if (parse_rhizome_bid_t(&bid, remainder, -1, &end) != -1) { if (strcmp(end, ".rhm") == 0) { handler = restful_rhizome_bid_rhm; remainder = ""; diff --git a/rhizome_types.h b/rhizome_types.h index 5a66a00b..92c688fb 100644 --- a/rhizome_types.h +++ b/rhizome_types.h @@ -80,7 +80,8 @@ typedef struct rhizome_bid_binary { #define alloca_tohex_rhizome_bid_t(bid) alloca_tohex((bid).binary, sizeof (*(rhizome_bid_t*)0).binary) int cmp_rhizome_bid_t(const rhizome_bid_t *a, const rhizome_bid_t *b); int str_to_rhizome_bid_t(rhizome_bid_t *bid, const char *hex); -int strn_to_rhizome_bid_t(rhizome_bid_t *bid, const char *hex, const char **endp); +int strn_to_rhizome_bid_t(rhizome_bid_t *bid, const char *hex, size_t hexlen); +int parse_rhizome_bid_t(rhizome_bid_t *bid, const char *hex, ssize_t hexlen, const char **endp); /* Fundamental data type: Rhizome File Hash * @@ -97,7 +98,8 @@ typedef struct rhizome_filehash_binary { #define alloca_tohex_rhizome_filehash_t(fh) alloca_tohex((fh).binary, sizeof (*(rhizome_filehash_t*)0).binary) int cmp_rhizome_filehash_t(const rhizome_filehash_t *a, const rhizome_filehash_t *b); int str_to_rhizome_filehash_t(rhizome_filehash_t *fh, const char *hex); -int strn_to_rhizome_filehash_t(rhizome_filehash_t *fh, const char *hex, const char **endp); +int strn_to_rhizome_filehash_t(rhizome_filehash_t *fh, const char *hex, size_t hexlen); +int parse_rhizome_filehash_t(rhizome_filehash_t *fh, const char *hex, ssize_t hexlen, const char **endp); /* Fundamental data type: Rhizome Bundle Key (BK) * @@ -119,7 +121,8 @@ int cmp_rhizome_bk_t(const rhizome_bk_t *a, const rhizome_bk_t *b); // The BK field can only be in hex format int str_to_rhizome_bk_t(rhizome_bk_t *bk, const char *hex); -int strn_to_rhizome_bk_t(rhizome_bk_t *bk, const char *hex, const char **endp); +int strn_to_rhizome_bk_t(rhizome_bk_t *bk, const char *hex, size_t hexlen); +int parse_rhizome_bk_t(rhizome_bk_t *bk, const char *hex, ssize_t hexlen, const char **endp); // The Bundle Secret can be given as hex or as a passphrase int str_to_rhizome_bsk_t(rhizome_bk_t *bsk, const char *text); diff --git a/serval_types.h b/serval_types.h index 7eb7ee93..466e63e5 100644 --- a/serval_types.h +++ b/serval_types.h @@ -54,7 +54,8 @@ typedef struct sid_binary { int cmp_sid_t(const sid_t *a, const sid_t *b); int str_to_sid_t(sid_t *sid, const char *hex); -int strn_to_sid_t(sid_t *sid, const char *hex, size_t hexlen, const char **endp); +int strn_to_sid_t(sid_t *sid, const char *hex, size_t hexlen); +int parse_sid_t(sid_t *sid, const char *hex, ssize_t hexlen, const char **endp); #define alloca_tohex_sas(sas) alloca_tohex((sas), SAS_SIZE) diff --git a/str.c b/str.c index 06a062c2..1eebb509 100644 --- a/str.c +++ b/str.c @@ -563,8 +563,9 @@ int str_startswith(const char *str, const char *substring, const char **afterp) return 1; } -int strn_startswith(const char *str, size_t len, const char *substring, const char **afterp) +int strn_startswith(const char *str, ssize_t len, const char *substring, const char **afterp) { + // if len == -1 then str must be nul terminated while (len && *substring && *substring == *str) --len, ++substring, ++str; if (*substring) diff --git a/str.h b/str.h index 4294419f..43a6e01c 100644 --- a/str.h +++ b/str.h @@ -371,9 +371,11 @@ int str_startswith(const char *str, const char *substring, const char **afterp); * sub-string. If so, return 1 and, if afterp is not NULL, set *afterp to point to the character * immediately following the substring. Otherwise return 0. * + * If len == -1 then is equivalent to str_startswith(). + * * @author Andrew Bettison */ -int strn_startswith(const char *str, size_t len, const char *substring, const char **afterp); +int strn_startswith(const char *str, ssize_t len, const char *substring, const char **afterp); /* Case-insensitive form of str_startswith(). * @author Andrew Bettison