/* * Copyright (c) 2016, Natacha Porté * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include #include "dict_tools.h" static bool check_length(Tuple *tuple, const char *context) { if (tuple->length == 1 || tuple->length == 2 || tuple->length == 4) { return true; } APP_LOG(APP_LOG_LEVEL_ERROR, "Unexpected length %" PRIu16 " in %s dictionary entry", tuple->length, context); return false; } static int32_t raw_read_int(Tuple *tuple) { switch (tuple->length) { case 1: return tuple->value->int8; case 2: return tuple->value->int16; case 4: return tuple->value->int32; default: return 0; } } static uint32_t raw_read_uint(Tuple *tuple) { switch (tuple->length) { case 1: return tuple->value->uint8; case 2: return tuple->value->uint16; case 4: return tuple->value->uint32; default: return 0; } } int32_t tuple_int(Tuple *tuple) { if (!tuple) return 0; switch (tuple->type) { case TUPLE_INT: if (!check_length(tuple, "integer")) return 0; return raw_read_int(tuple); case TUPLE_UINT: if (!check_length(tuple, "integer")) return 0; uint32_t u = raw_read_uint(tuple); if (u > 2147483647) { APP_LOG(APP_LOG_LEVEL_ERROR, "Integer overflow in signed dictionary entry %" PRIu32, u); return 0; } return u; default: APP_LOG(APP_LOG_LEVEL_ERROR, "Unexpected type %d for integer dictionary entry", (int)tuple->type); return 0; } } uint32_t tuple_uint(Tuple *tuple) { if (!tuple) return 0; switch (tuple->type) { case TUPLE_UINT: if (!check_length(tuple, "unsigned")) return 0; return raw_read_uint(tuple); case TUPLE_INT: if (!check_length(tuple, "unsigned")) return 0; int32_t i = raw_read_int(tuple); if (i < 0) { APP_LOG(APP_LOG_LEVEL_ERROR, "Integer underflow in unsigned dictionary entry %" PRIi32, i); return 0; } return i; default: APP_LOG(APP_LOG_LEVEL_ERROR, "Unexpected type %d for unsigned dictionary entry", (int)tuple->type); return 0; } }