diff options
| -rw-r--r-- | src/bplist.c | 12 | ||||
| -rw-r--r-- | src/time64.c | 6 |
2 files changed, 16 insertions, 2 deletions
diff --git a/src/bplist.c b/src/bplist.c index 8168572..e5ace3a 100644 --- a/src/bplist.c +++ b/src/bplist.c @@ -237,6 +237,8 @@ struct bplist_data { uint8_t offset_size; const char* offset_table; uint32_t level; + uint64_t nodes_parsed; + uint64_t max_nodes; ptrarray_t* used_indexes; plist_err_t err; }; @@ -866,6 +868,14 @@ static plist_t parse_bin_node_at_index(struct bplist_data *bplist, uint32_t node return NULL; } + /* Objects can be referenced multiple times, so limit the total number of + nodes created to avoid excessive memory use from reference expansion. */ + if (++bplist->nodes_parsed > bplist->max_nodes) { + PLIST_BIN_ERR("too many nodes created while parsing (reference expansion?)\n"); + bplist->err = PLIST_ERR_PARSE; + return NULL; + } + /* check nesting depth */ if (bplist->level > PLIST_MAX_NESTING_DEPTH) { PLIST_BIN_ERR("maximum nesting depth (%u) exceeded\n",(unsigned)PLIST_MAX_NESTING_DEPTH); @@ -1003,6 +1013,8 @@ plist_err_t plist_from_bin(const char *plist_bin, uint32_t length, plist_t * pli bplist.offset_size = offset_size; bplist.offset_table = offset_table; bplist.level = 0; + bplist.nodes_parsed = 0; + bplist.max_nodes = num_objects * 16 + 65536; bplist.used_indexes = ptr_array_new(16); bplist.err = PLIST_ERR_SUCCESS; diff --git a/src/time64.c b/src/time64.c index 218088e..6a9218c 100644 --- a/src/time64.c +++ b/src/time64.c @@ -45,6 +45,7 @@ gmtime64_r() is a 64-bit equivalent of gmtime_r(). #include <string.h> #include <time.h> #include <errno.h> +#include <limits.h> #include "time64.h" #include "time64_limits.h" @@ -125,7 +126,7 @@ static const char dow_year_start[SOLAR_CYCLE_LENGTH] = { #define CHEAT_DAYS (1199145600 / 24 / 60 / 60) #define CHEAT_YEARS 108 -#define IS_LEAP(n) ((!(((n) + 1900) % 400) || (!(((n) + 1900) % 4) && (((n) + 1900) % 100))) != 0) +#define IS_LEAP(n) ((!(((Year)(n) + 1900) % 400) || (!(((Year)(n) + 1900) % 4) && (((Year)(n) + 1900) % 100))) != 0) #define WRAP(a,b,m) ((a) = ((a) < 0 ) ? ((b)--, (a) + (m)) : (a)) #ifdef USE_SYSTEM_LOCALTIME @@ -649,7 +650,8 @@ struct TM *gmtime64_r (const Time64_T *in_time, struct TM *p) } p->tm_year = year; - if( p->tm_year != year ) { + /* The calendar year (tm_year + 1900) must also fit in an int, e.g. for strftime() */ + if( p->tm_year != year || year > (Year)INT_MAX - 1900 || year < (Year)INT_MIN ) { #ifdef EOVERFLOW errno = EOVERFLOW; #endif |
