summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/bplist.c12
-rw-r--r--src/time64.c6
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