From 0a4c77dbff8db7210e5aa905cf3f6ebd170e14cb Mon Sep 17 00:00:00 2001 From: Matthias Kovatsch Date: Fri, 20 Jan 2012 16:11:45 +0100 Subject: [PATCH] Fixed snprintf() return value handling. --- apps/er-coap-07/er-coap-07-engine.c | 15 +++++-- .../er-rest-example/rest-server-example.c | 45 ++++++++++--------- 2 files changed, 35 insertions(+), 25 deletions(-) diff --git a/apps/er-coap-07/er-coap-07-engine.c b/apps/er-coap-07/er-coap-07-engine.c index 245072b8e..d2e4f9b63 100644 --- a/apps/er-coap-07/er-coap-07-engine.c +++ b/apps/er-coap-07/er-coap-07-engine.c @@ -301,13 +301,14 @@ coap_set_rest_status(void *packet, unsigned int code) /*-----------------------------------------------------------------------------------*/ /*- Server part ---------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/ + /* The discover resource is automatically included for CoAP. */ RESOURCE(well_known_core, METHOD_GET, ".well-known/core", "ct=40"); void well_known_core_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) { - size_t strpos = 0; - size_t bufpos = 0; + size_t strpos = 0; /* position in overall string (which is larger than the buffer) */ + size_t bufpos = 0; /* position within buffer (bytes written) */ size_t tmplen = 0; resource_t* resource = NULL; @@ -333,6 +334,10 @@ well_known_core_handler(void* request, void* response, uint8_t *buffer, uint16_t bufpos += snprintf((char *) buffer + bufpos, preferred_size - bufpos + 1, "%s", resource->url + ((*offset-(int32_t)strpos > 0) ? (*offset-(int32_t)strpos) : 0)); /* minimal-net requires these casts */ + if (bufpos >= preferred_size) + { + break; + } } strpos += tmplen; @@ -355,6 +360,10 @@ well_known_core_handler(void* request, void* response, uint8_t *buffer, uint16_t { bufpos += snprintf((char *) buffer + bufpos, preferred_size - bufpos + 1, "%s", resource->attributes + (*offset-(int32_t)strpos > 0 ? *offset-(int32_t)strpos : 0)); + if (bufpos >= preferred_size) + { + break; + } } strpos += tmplen; } @@ -397,7 +406,7 @@ well_known_core_handler(void* request, void* response, uint8_t *buffer, uint16_t else { PRINTF("res: MORE at %s (%p)\n", resource->url, resource); - *offset += bufpos; + *offset += preferred_size; } } /*-----------------------------------------------------------------------------------*/ diff --git a/examples/er-rest-example/rest-server-example.c b/examples/er-rest-example/rest-server-example.c index 8373d9917..d76b622c1 100644 --- a/examples/er-rest-example/rest-server-example.c +++ b/examples/er-rest-example/rest-server-example.c @@ -45,14 +45,14 @@ /* Define which resources to include to meet memory constraints. */ #define REST_RES_HELLO 1 -#define REST_RES_MIRROR 0 +#define REST_RES_MIRROR 0 /* causes largest code size */ #define REST_RES_CHUNKS 1 -#define REST_RES_POLLING 0 +#define REST_RES_POLLING 1 #define REST_RES_EVENT 1 -#define REST_RES_LEDS 0 +#define REST_RES_LEDS 1 #define REST_RES_TOGGLE 1 #define REST_RES_LIGHT 1 -#define REST_RES_BATTERY 0 +#define REST_RES_BATTERY 1 @@ -173,28 +173,29 @@ mirror_handler(void* request, void* response, uint8_t *buffer, uint16_t preferre int strpos = 0; /* snprintf() counts the terminating '\0' to the size parameter. - * Add +1 to fill the complete buffer. - * The additional byte is taken care of by allocating REST_MAX_CHUNK_SIZE+1 bytes in the REST framework. */ + * The additional byte is taken care of by allocating REST_MAX_CHUNK_SIZE+1 bytes in the REST framework. + * Add +1 to fill the complete buffer. */ strpos += snprintf((char *)buffer, REST_MAX_CHUNK_SIZE+1, "CT %u\n", content_type); /* Some getters such as for ETag or Location are omitted, as these options should not appear in a request. * Max-Age might appear in HTTP requests or used for special purposes in CoAP. */ - if (REST.get_header_max_age(request, &max_age)) + if (strpos<=REST_MAX_CHUNK_SIZE && REST.get_header_max_age(request, &max_age)) { strpos += snprintf((char *)buffer+strpos, REST_MAX_CHUNK_SIZE-strpos+1, "MA %lu\n", max_age); } - if ((len = REST.get_header_host(request, &str))) + + if (strpos<=REST_MAX_CHUNK_SIZE && (len = REST.get_header_host(request, &str))) { strpos += snprintf((char *)buffer+strpos, REST_MAX_CHUNK_SIZE-strpos+1, "UH %.*s\n", len, str); } /* CoAP-specific example: actions not required for normal RESTful Web service. */ #if WITH_COAP > 1 - if (coap_get_header_observe(request, &observe)) + if (strpos<=REST_MAX_CHUNK_SIZE && coap_get_header_observe(request, &observe)) { strpos += snprintf((char *)buffer+strpos, REST_MAX_CHUNK_SIZE-strpos+1, "Ob %lu\n", observe); } - if ((len = coap_get_header_token(request, &bytes))) + if (strpos<=REST_MAX_CHUNK_SIZE && (len = coap_get_header_token(request, &bytes))) { strpos += snprintf((char *)buffer+strpos, REST_MAX_CHUNK_SIZE-strpos+1, "To 0x"); int index = 0; @@ -203,7 +204,7 @@ mirror_handler(void* request, void* response, uint8_t *buffer, uint16_t preferre } strpos += snprintf((char *)buffer+strpos, REST_MAX_CHUNK_SIZE-strpos+1, "\n"); } - if ((len = coap_get_header_etag(request, &bytes))) + if (strpos<=REST_MAX_CHUNK_SIZE && (len = coap_get_header_etag(request, &bytes))) { strpos += snprintf((char *)buffer+strpos, REST_MAX_CHUNK_SIZE-strpos+1, "ET 0x"); int index = 0; @@ -212,34 +213,34 @@ mirror_handler(void* request, void* response, uint8_t *buffer, uint16_t preferre } strpos += snprintf((char *)buffer+strpos, REST_MAX_CHUNK_SIZE-strpos+1, "\n"); } - if ((len = coap_get_header_uri_path(request, &str))) + if (strpos<=REST_MAX_CHUNK_SIZE && (len = coap_get_header_uri_path(request, &str))) { strpos += snprintf((char *)buffer+strpos, REST_MAX_CHUNK_SIZE-strpos+1, "UP "); strpos += snprintf((char *)buffer+strpos, REST_MAX_CHUNK_SIZE-strpos+1, "%.*s\n", len, str); } #if WITH_COAP == 3 - if ((len = coap_get_header_location(request, &str))) + if (strpos<=REST_MAX_CHUNK_SIZE && (len = coap_get_header_location(request, &str))) { strpos += snprintf((char *)buffer+strpos, REST_MAX_CHUNK_SIZE-strpos+1, "Lo %.*s\n", len, str); } - if (coap_get_header_block(request, &block_num, &block_more, &block_size, NULL)) /* This getter allows NULL pointers to get only a subset of the block parameters. */ + if (strpos<=REST_MAX_CHUNK_SIZE && coap_get_header_block(request, &block_num, &block_more, &block_size, NULL)) /* This getter allows NULL pointers to get only a subset of the block parameters. */ { strpos += snprintf((char *)buffer+strpos, REST_MAX_CHUNK_SIZE-strpos+1, "Bl %lu%s (%u)\n", block_num, block_more ? "+" : "", block_size); } #elif WITH_COAP >= 5 - if ((len = coap_get_header_location_path(request, &str))) + if (strpos<=REST_MAX_CHUNK_SIZE && (len = coap_get_header_location_path(request, &str))) { strpos += snprintf((char *)buffer+strpos, REST_MAX_CHUNK_SIZE-strpos+1, "LP %.*s\n", len, str); } - if ((len = coap_get_header_location_query(request, &str))) + if (strpos<=REST_MAX_CHUNK_SIZE && (len = coap_get_header_location_query(request, &str))) { strpos += snprintf((char *)buffer+strpos, REST_MAX_CHUNK_SIZE-strpos+1, "LQ %.*s\n", len, str); } - if (coap_get_header_block2(request, &block_num, &block_more, &block_size, NULL)) /* This getter allows NULL pointers to get only a subset of the block parameters. */ + if (strpos<=REST_MAX_CHUNK_SIZE && coap_get_header_block2(request, &block_num, &block_more, &block_size, NULL)) /* This getter allows NULL pointers to get only a subset of the block parameters. */ { strpos += snprintf((char *)buffer+strpos, REST_MAX_CHUNK_SIZE-strpos+1, "B2 %lu%s (%u)\n", block_num, block_more ? "+" : "", block_size); } - if (coap_get_header_block1(request, &block_num, &block_more, &block_size, NULL)) /* This getter allows NULL pointers to get only a subset of the block parameters. */ + if (strpos<=REST_MAX_CHUNK_SIZE && coap_get_header_block1(request, &block_num, &block_more, &block_size, NULL)) /* This getter allows NULL pointers to get only a subset of the block parameters. */ { strpos += snprintf((char *)buffer+strpos, REST_MAX_CHUNK_SIZE-strpos+1, "B1 %lu%s (%u)\n", block_num, block_more ? "+" : "", block_size); } @@ -250,16 +251,16 @@ mirror_handler(void* request, void* response, uint8_t *buffer, uint16_t preferre #endif #endif /* CoAP-specific example */ - if ((len = REST.get_query(request, &query))) + if (strpos<=REST_MAX_CHUNK_SIZE && (len = REST.get_query(request, &query))) { strpos += snprintf((char *)buffer+strpos, REST_MAX_CHUNK_SIZE-strpos+1, "Qu %.*s\n", len, query); } - if ((len = REST.get_request_payload(request, &bytes))) + if (strpos<=REST_MAX_CHUNK_SIZE && (len = REST.get_request_payload(request, &bytes))) { strpos += snprintf((char *)buffer+strpos, REST_MAX_CHUNK_SIZE-strpos+1, "%.*s", len, bytes); } - if (strpos == REST_MAX_CHUNK_SIZE) + if (strpos >= REST_MAX_CHUNK_SIZE) { buffer[REST_MAX_CHUNK_SIZE-1] = 0xBB; /* 'ยป' to indicate truncation */ } @@ -332,7 +333,7 @@ chunks_handler(void* request, void* response, uint8_t *buffer, uint16_t preferre strpos = preferred_size; } - /* Truncate if above total size. */ + /* Truncate if above CHUNKS_TOTAL bytes. */ if (*offset+(int32_t)strpos > CHUNKS_TOTAL) { strpos = CHUNKS_TOTAL - *offset;