@@ -189,20 +189,29 @@ static inline int template_callback_false(unpack_user* u, msgpack_object* o)
189189
190190static inline int template_callback_array (unpack_user * u , unsigned int n , msgpack_object * o )
191191{
192- unsigned int size ;
192+ size_t size ;
193+ // Let's leverage the fact that sizeof(msgpack_object) is a compile time constant
194+ // to check for int overflows.
195+ // Note - while n is constrained to 32-bit, the product of n * sizeof(msgpack_object)
196+ // might not be constrained to 4GB on 64-bit systems
197+ #if SIZE_MAX == UINT_MAX
198+ if (n > SIZE_MAX /sizeof (msgpack_object ))
199+ return MSGPACK_UNPACK_NOMEM_ERROR ;
200+ #endif
201+
193202 o -> type = MSGPACK_OBJECT_ARRAY ;
194203 o -> via .array .size = 0 ;
195- size = n * sizeof (msgpack_object );
196- if (size / sizeof (msgpack_object ) != n ) {
197- // integer overflow
198- return MSGPACK_UNPACK_NOMEM_ERROR ;
199- }
204+
205+ size = n * sizeof (msgpack_object );
206+
200207 if (* u -> z == NULL ) {
201208 * u -> z = msgpack_zone_new (MSGPACK_ZONE_CHUNK_SIZE );
202209 if (* u -> z == NULL ) {
203210 return MSGPACK_UNPACK_NOMEM_ERROR ;
204211 }
205212 }
213+
214+ // Unsure whether size = 0 should be an error, and if so, what to return
206215 o -> via .array .ptr = (msgpack_object * )msgpack_zone_malloc (* u -> z , size );
207216 if (o -> via .array .ptr == NULL ) { return MSGPACK_UNPACK_NOMEM_ERROR ; }
208217 return 0 ;
@@ -222,20 +231,31 @@ static inline int template_callback_array_item(unpack_user* u, msgpack_object* c
222231
223232static inline int template_callback_map (unpack_user * u , unsigned int n , msgpack_object * o )
224233{
225- unsigned int size ;
234+ size_t size ;
235+ // Let's leverage the fact that sizeof(msgpack_object_kv) is a compile time constant
236+ // to check for int overflows
237+ // Note - while n is constrained to 32-bit, the product of n * sizeof(msgpack_object)
238+ // might not be constrained to 4GB on 64-bit systems
239+
240+ // Note - this will always be false on 64-bit systems
241+ #if SIZE_MAX == UINT_MAX
242+ if (n > SIZE_MAX /sizeof (msgpack_object_kv ))
243+ return MSGPACK_UNPACK_NOMEM_ERROR ;
244+ #endif
245+
226246 o -> type = MSGPACK_OBJECT_MAP ;
227247 o -> via .map .size = 0 ;
228- size = n * sizeof (msgpack_object_kv );
229- if (size / sizeof (msgpack_object_kv ) != n ) {
230- // integer overflow
231- return MSGPACK_UNPACK_NOMEM_ERROR ;
232- }
248+
249+ size = n * sizeof (msgpack_object_kv );
250+
233251 if (* u -> z == NULL ) {
234252 * u -> z = msgpack_zone_new (MSGPACK_ZONE_CHUNK_SIZE );
235253 if (* u -> z == NULL ) {
236254 return MSGPACK_UNPACK_NOMEM_ERROR ;
237255 }
238256 }
257+
258+ // Should size = 0 be an error? If so, what error to return?
239259 o -> via .map .ptr = (msgpack_object_kv * )msgpack_zone_malloc (* u -> z , size );
240260 if (o -> via .map .ptr == NULL ) { return MSGPACK_UNPACK_NOMEM_ERROR ; }
241261 return 0 ;
0 commit comments