1717#include < gromox/mapidefs.h>
1818#include < gromox/util.hpp>
1919#define TRY (expr ) do { pack_result klfdv{expr}; if (klfdv != EXT_ERR_SUCCESS) return klfdv; } while (false )
20+ #define CLAMP16 (v ) ((v) = std::min((v), static_cast <uint16_t >(UINT16_MAX)))
21+ #define CLAMP32 (v ) ((v) = std::min((v), static_cast <uint32_t >(UINT32_MAX)))
2022
2123using namespace gromox ;
2224
@@ -333,6 +335,7 @@ pack_result EXT_PULL::g_uint16_an(SHORT_ARRAY *r, uint32_t count)
333335pack_result EXT_PULL::g_uint16_a (SHORT_ARRAY *r)
334336{
335337 TRY (g_uint32 (&r->count ));
338+ CLAMP32 (r->count );
336339 return g_uint16_an (r, r->count );
337340}
338341
@@ -356,6 +359,7 @@ pack_result EXT_PULL::g_uint32_an(LONG_ARRAY *r, uint32_t count)
356359pack_result EXT_PULL::g_uint32_a (LONG_ARRAY *r)
357360{
358361 TRY (g_uint32 (&r->count ));
362+ CLAMP32 (r->count );
359363 return g_uint32_an (r, r->count );
360364}
361365
@@ -379,13 +383,15 @@ pack_result EXT_PULL::g_uint64_an(LONGLONG_ARRAY *r, uint32_t count)
379383pack_result EXT_PULL::g_uint64_a (LONGLONG_ARRAY *r)
380384{
381385 TRY (g_uint32 (&r->count ));
386+ CLAMP32 (r->count );
382387 return g_uint64_an (r, r->count );
383388}
384389
385390pack_result EXT_PULL::g_uint64_sa (LONGLONG_ARRAY *r)
386391{
387392 uint16_t count;
388393 TRY (g_uint16 (&count));
394+ CLAMP16 (count);
389395 return g_uint64_an (r, count);
390396}
391397
@@ -409,6 +415,7 @@ pack_result EXT_PULL::g_float_an(FLOAT_ARRAY *r, uint32_t count)
409415pack_result EXT_PULL::g_float_a (FLOAT_ARRAY *r)
410416{
411417 TRY (g_uint32 (&r->count ));
418+ CLAMP32 (r->count );
412419 return g_float_an (r, r->count );
413420}
414421
@@ -432,6 +439,7 @@ pack_result EXT_PULL::g_double_an(DOUBLE_ARRAY *r, uint32_t count)
432439pack_result EXT_PULL::g_double_a (DOUBLE_ARRAY *r)
433440{
434441 TRY (g_uint32 (&r->count ));
442+ CLAMP32 (r->count );
435443 return g_double_an (r, r->count );
436444}
437445
@@ -442,6 +450,7 @@ pack_result EXT_PULL::g_bin_a(BINARY_ARRAY *r)
442450 r->pbin = NULL ;
443451 return EXT_ERR_SUCCESS;
444452 }
453+ CLAMP32 (r->count );
445454 r->pbin = anew<BINARY>(r->count );
446455 if (r->pbin == nullptr ) {
447456 r->count = 0 ;
@@ -471,6 +480,7 @@ pack_result EXT_PULL::g_str_a(STRING_ARRAY *r)
471480 r->ppstr = NULL ;
472481 return EXT_ERR_SUCCESS;
473482 }
483+ CLAMP32 (r->count );
474484 r->ppstr = anew<char *>(r->count );
475485 if (r->ppstr == nullptr ) {
476486 r->count = 0 ;
@@ -499,6 +509,7 @@ pack_result EXT_PULL::g_wstr_a(STRING_ARRAY *r)
499509 r->ppstr = NULL ;
500510 return EXT_ERR_SUCCESS;
501511 }
512+ CLAMP32 (r->count );
502513 r->ppstr = anew<char *>(r->count );
503514 if (r->ppstr == nullptr ) {
504515 r->count = 0 ;
@@ -540,19 +551,22 @@ pack_result EXT_PULL::g_guid_an(GUID_ARRAY *r, uint32_t count)
540551pack_result EXT_PULL::g_guid_a (GUID_ARRAY *r)
541552{
542553 TRY (g_uint32 (&r->count ));
554+ CLAMP32 (r->count );
543555 return g_guid_an (r, r->count );
544556}
545557
546558static pack_result ext_buffer_pull_restriction_and_or (EXT_PULL *pext,
547559 RESTRICTION_AND_OR *r)
548560{
549561 auto &ext = *pext;
550- uint16_t count;
551562
552563 if (ext.m_flags & EXT_FLAG_WCOUNT) {
553564 TRY (pext->g_uint32 (&r->count ));
565+ CLAMP32 (r->count );
554566 } else {
567+ uint16_t count;
555568 TRY (pext->g_uint16 (&count));
569+ CLAMP16 (count);
556570 r->count = count;
557571 }
558572 if (r->count == 0 ) {
@@ -890,6 +904,7 @@ static pack_result ext_buffer_pull_recipient_block(EXT_PULL *pext, RECIPIENT_BLO
890904 TRY (pext->g_uint16 (&r->count ));
891905 if (r->count == 0 )
892906 return EXT_ERR_FORMAT;
907+ CLAMP16 (r->count );
893908 r->ppropval = pext->anew <TAGGED_PROPVAL>(r->count );
894909 if (r->ppropval == nullptr ) {
895910 r->count = 0 ;
@@ -906,6 +921,7 @@ static pack_result ext_buffer_pull_forwarddelegate_action(EXT_PULL *pext,
906921 TRY (pext->g_uint16 (&r->count ));
907922 if (r->count == 0 )
908923 return EXT_ERR_FORMAT;
924+ CLAMP16 (r->count );
909925 r->pblock = pext->anew <RECIPIENT_BLOCK>(r->count );
910926 if (r->pblock == nullptr ) {
911927 r->count = 0 ;
@@ -992,6 +1008,7 @@ pack_result EXT_PULL::g_rule_actions(RULE_ACTIONS *r)
9921008 TRY (g_uint16 (&r->count ));
9931009 if (r->count == 0 )
9941010 return EXT_ERR_FORMAT;
1011+ CLAMP16 (r->count );
9951012 r->pblock = anew<ACTION_BLOCK>(r->count );
9961013 if (r->pblock == nullptr ) {
9971014 r->count = 0 ;
@@ -1100,6 +1117,7 @@ pack_result EXT_PULL::g_proptag_a(PROPTAG_ARRAY *r)
11001117 r->pproptag = NULL ;
11011118 return EXT_ERR_SUCCESS;
11021119 }
1120+ CLAMP16 (r->count );
11031121 r->pproptag = anew<uint32_t >(strange_roundup (r->count , SR_GROW_PROPTAG_ARRAY));
11041122 if (r->pproptag == nullptr ) {
11051123 r->count = 0 ;
@@ -1117,6 +1135,7 @@ pack_result EXT_PULL::g_proptag_a(LPROPTAG_ARRAY *r)
11171135 r->pproptag = nullptr ;
11181136 return EXT_ERR_SUCCESS;
11191137 }
1138+ CLAMP32 (r->cvalues );
11201139 r->pproptag = anew<uint32_t >(strange_roundup (r->cvalues , SR_GROW_PROPTAG_ARRAY));
11211140 if (r->pproptag == nullptr ) {
11221141 r->cvalues = 0 ;
@@ -1157,6 +1176,7 @@ pack_result EXT_PULL::g_propname_a(PROPNAME_ARRAY *r)
11571176 r->ppropname = NULL ;
11581177 return EXT_ERR_SUCCESS;
11591178 }
1179+ CLAMP16 (r->count );
11601180 r->ppropname = anew<PROPERTY_NAME>(r->count );
11611181 if (r->ppropname == nullptr ) {
11621182 r->count = 0 ;
@@ -1174,6 +1194,7 @@ pack_result EXT_PULL::g_tpropval_a(TPROPVAL_ARRAY *r)
11741194 r->ppropval = NULL ;
11751195 return EXT_ERR_SUCCESS;
11761196 }
1197+ CLAMP16 (r->count );
11771198 r->ppropval = anew<TAGGED_PROPVAL>(strange_roundup (r->count , SR_GROW_TAGGED_PROPVAL));
11781199 if (r->ppropval == nullptr ) {
11791200 r->count = 0 ;
@@ -1191,6 +1212,7 @@ pack_result EXT_PULL::g_tpropval_a(LTPROPVAL_ARRAY *r)
11911212 r->propval = nullptr ;
11921213 return EXT_ERR_SUCCESS;
11931214 }
1215+ CLAMP32 (r->count );
11941216 r->propval = anew<TAGGED_PROPVAL>(strange_roundup (r->count , SR_GROW_TAGGED_PROPVAL));
11951217 if (r->propval == nullptr ) {
11961218 r->count = 0 ;
@@ -1208,6 +1230,7 @@ pack_result EXT_PULL::g_tarray_set(TARRAY_SET *r)
12081230 r->pparray = NULL ;
12091231 return EXT_ERR_SUCCESS;
12101232 }
1233+ CLAMP32 (r->count );
12111234 r->pparray = anew<TPROPVAL_ARRAY *>(strange_roundup (r->count , SR_GROW_TPROPVAL_ARRAY));
12121235 if (r->pparray == nullptr ) {
12131236 r->count = 0 ;
@@ -1232,6 +1255,7 @@ static pack_result ext_buffer_pull_property_problem(EXT_PULL *pext, PROPERTY_PRO
12321255pack_result EXT_PULL::g_problem_a (PROBLEM_ARRAY *r)
12331256{
12341257 TRY (g_uint16 (&r->count ));
1258+ CLAMP16 (r->count );
12351259 r->pproblem = anew<PROPERTY_PROBLEM>(r->count );
12361260 if (r->pproblem == nullptr ) {
12371261 r->count = 0 ;
@@ -1312,6 +1336,7 @@ static pack_result ext_buffer_pull_ext_recipient_block(EXT_PULL *pext,
13121336 TRY (pext->g_uint32 (&r->count ));
13131337 if (r->count == 0 )
13141338 return EXT_ERR_FORMAT;
1339+ CLAMP32 (r->count );
13151340 r->ppropval = pext->anew <TAGGED_PROPVAL>(r->count );
13161341 if (r->ppropval == nullptr ) {
13171342 r->count = 0 ;
@@ -1328,6 +1353,7 @@ static pack_result ext_buffer_pull_ext_forwarddelegate_action(EXT_PULL *pext,
13281353 TRY (pext->g_uint32 (&r->count ));
13291354 if (r->count == 0 )
13301355 return EXT_ERR_FORMAT;
1356+ CLAMP32 (r->count );
13311357 r->pblock = pext->anew <EXT_RECIPIENT_BLOCK>(r->count );
13321358 if (r->pblock == nullptr ) {
13331359 r->count = 0 ;
@@ -1396,6 +1422,7 @@ pack_result EXT_PULL::g_ext_rule_actions(EXT_RULE_ACTIONS *r)
13961422 TRY (g_uint32 (&r->count ));
13971423 if (r->count == 0 )
13981424 return EXT_ERR_FORMAT;
1425+ CLAMP32 (r->count );
13991426 r->pblock = anew<EXT_ACTION_BLOCK>(r->count );
14001427 if (r->pblock == nullptr ) {
14011428 r->count = 0 ;
@@ -1416,6 +1443,7 @@ pack_result EXT_PULL::g_namedprop_info(NAMEDPROPERTY_INFO *r)
14161443 r->ppropname = NULL ;
14171444 return EXT_ERR_SUCCESS;
14181445 }
1446+ CLAMP16 (r->count );
14191447 r->ppropid = anew<uint16_t >(r->count );
14201448 if (r->ppropid == nullptr ) {
14211449 r->count = 0 ;
@@ -1503,6 +1531,7 @@ pack_result EXT_PULL::g_sortorder(SORT_ORDER *r)
15031531pack_result EXT_PULL::g_sortorder_set (SORTORDER_SET *r)
15041532{
15051533 TRY (g_uint16 (&r->count ));
1534+ CLAMP16 (r->count );
15061535 TRY (g_uint16 (&r->ccategories ));
15071536 TRY (g_uint16 (&r->cexpanded ));
15081537 if (r->count == 0 || r->ccategories > r->count || r->cexpanded > r->ccategories )
@@ -1674,6 +1703,7 @@ pack_result EXT_PULL::g_flatentry_a(BINARY_ARRAY *r)
16741703 uint8_t pad_len;
16751704
16761705 TRY (g_uint32 (&r->count ));
1706+ CLAMP32 (r->count );
16771707 r->pbin = anew<BINARY>(r->count );
16781708 if (r->pbin == nullptr ) {
16791709 r->count = 0 ;
@@ -1701,6 +1731,7 @@ pack_result EXT_PULL::g_eid_a(EID_ARRAY *r)
17011731 r->pids = NULL ;
17021732 return EXT_ERR_SUCCESS;
17031733 }
1734+ CLAMP32 (r->count );
17041735 r->pids = anew<uint64_t >(r->count );
17051736 if (r->pids == nullptr ) {
17061737 r->count = 0 ;
@@ -1774,6 +1805,7 @@ pack_result EXT_PULL::g_tzdef(TIMEZONEDEFINITION *r)
17741805 return EXT_ERR_ALLOC;
17751806 strcpy (r->keyname , tmp_buff1);
17761807 TRY (g_uint16 (&r->crules ));
1808+ CLAMP16 (r->crules );
17771809 r->prules = anew<TZRULE>(r->crules );
17781810 if (r->prules == nullptr ) {
17791811 r->crules = 0 ;
@@ -1899,6 +1931,7 @@ static pack_result ext_buffer_pull_extendedexception(EXT_PULL *pext,
18991931 }
19001932 if (overrideflags & ARO_SUBJECT) {
19011933 TRY (pext->g_uint16 (&tmp_len));
1934+ CLAMP16 (tmp_len);
19021935 tmp_len *= 2 ;
19031936 std::unique_ptr<char []> pbuff;
19041937 try {
@@ -1919,6 +1952,7 @@ static pack_result ext_buffer_pull_extendedexception(EXT_PULL *pext,
19191952 }
19201953 if (overrideflags & ARO_LOCATION) {
19211954 TRY (pext->g_uint16 (&tmp_len));
1955+ CLAMP16 (tmp_len);
19221956 tmp_len *= 2 ;
19231957 std::unique_ptr<char []> pbuff;
19241958 try {
@@ -1968,6 +2002,7 @@ pack_result EXT_PULL::g_recpat(RECURRENCE_PATTERN *r)
19682002 TRY (g_uint32 (&r->occurrencecount ));
19692003 TRY (g_uint32 (&r->firstdow ));
19702004 TRY (g_uint32 (&r->deletedinstancecount ));
2005+ CLAMP32 (r->deletedinstancecount );
19712006 if (r->deletedinstancecount == 0 ) {
19722007 r->pdeletedinstancedates = NULL ;
19732008 } else {
@@ -1980,6 +2015,7 @@ pack_result EXT_PULL::g_recpat(RECURRENCE_PATTERN *r)
19802015 for (size_t i = 0 ; i < r->deletedinstancecount ; ++i)
19812016 TRY (g_uint32 (&r->pdeletedinstancedates [i]));
19822017 TRY (g_uint32 (&r->modifiedinstancecount ));
2018+ CLAMP32 (r->modifiedinstancecount );
19832019 if (r->modifiedinstancecount == 0 ) {
19842020 r->pmodifiedinstancedates = NULL ;
19852021 } else {
@@ -2003,6 +2039,7 @@ pack_result EXT_PULL::g_apptrecpat(APPOINTMENT_RECUR_PAT *r)
20032039 TRY (g_uint32 (&r->starttimeoffset ));
20042040 TRY (g_uint32 (&r->endtimeoffset ));
20052041 TRY (g_uint16 (&r->exceptioncount ));
2042+ CLAMP16 (r->exceptioncount );
20062043 if (r->exceptioncount == 0 ) {
20072044 r->pexceptioninfo = NULL ;
20082045 r->pextendedexception = NULL ;
@@ -2088,6 +2125,7 @@ static pack_result ext_buffer_pull_attachment_list(EXT_PULL *pext, ATTACHMENT_LI
20882125 uint8_t tmp_byte;
20892126
20902127 TRY (pext->g_uint16 (&r->count ));
2128+ CLAMP16 (r->count );
20912129 r->pplist = pext->anew <ATTACHMENT_CONTENT *>(strange_roundup (r->count , SR_GROW_ATTACHMENT_CONTENT));
20922130 if (r->pplist == nullptr ) {
20932131 r->count = 0 ;
0 commit comments