Mercurial > hg > freeDiameter
comparison libfdproto/dictionary.c @ 1316:2e868f71832f
Tentative fix for invalid pointers reported by Thomas.
author | Sebastien Decugis <sdecugis@freediameter.net> |
---|---|
date | Sat, 10 Dec 2016 22:12:02 +0800 |
parents | ab6457399be2 |
children | ab7cb954f17e |
comparison
equal
deleted
inserted
replaced
1315:8662db9f6105 | 1316:2e868f71832f |
---|---|
259 | 259 |
260 fd_list_init(&obj->disp_cbs, NULL); | 260 fd_list_init(&obj->disp_cbs, NULL); |
261 } | 261 } |
262 | 262 |
263 /* Initialize the "data" part of an object */ | 263 /* Initialize the "data" part of an object */ |
264 static int init_object_data(struct dict_object * dest, void * source, enum dict_object_type type) | 264 static int init_object_data(struct dict_object * dest, void * source, enum dict_object_type type, int dupos) |
265 { | 265 { |
266 TRACE_ENTRY("%p %p %d", dest, source, type); | 266 TRACE_ENTRY("%p %p %d", dest, source, type); |
267 CHECK_PARAMS( dest && source && CHECK_TYPE(type) ); | 267 CHECK_PARAMS( dest && source && CHECK_TYPE(type) ); |
268 | 268 |
269 /* Generic: copy the full data structure */ | 269 /* Generic: copy the full data structure */ |
284 DUP_string_len( dest->data.type.type_name, &dest->datastr_len ); | 284 DUP_string_len( dest->data.type.type_name, &dest->datastr_len ); |
285 break; | 285 break; |
286 | 286 |
287 case DICT_ENUMVAL: | 287 case DICT_ENUMVAL: |
288 DUP_string_len( dest->data.enumval.enum_name, &dest->datastr_len ); | 288 DUP_string_len( dest->data.enumval.enum_name, &dest->datastr_len ); |
289 if (dupos) { | |
290 // we also need to duplicate the octetstring constant value since it is a pointer. | |
291 dest->data.enumval.enum_value.os.data = os0dup( | |
292 ((struct dict_enumval_data *)source)->enum_value.os.data, | |
293 ((struct dict_enumval_data *)source)->enum_value.os.len | |
294 ); | |
295 } | |
289 break; | 296 break; |
290 | 297 |
291 case DICT_AVP: | 298 case DICT_AVP: |
292 DUP_string_len( dest->data.avp.avp_name, &dest->datastr_len ); | 299 DUP_string_len( dest->data.avp.avp_name, &dest->datastr_len ); |
293 break; | 300 break; |
1602 | 1609 |
1603 /* Add a new object in the dictionary */ | 1610 /* Add a new object in the dictionary */ |
1604 int fd_dict_new ( struct dictionary * dict, enum dict_object_type type, void * data, struct dict_object * parent, struct dict_object **ref ) | 1611 int fd_dict_new ( struct dictionary * dict, enum dict_object_type type, void * data, struct dict_object * parent, struct dict_object **ref ) |
1605 { | 1612 { |
1606 int ret = 0; | 1613 int ret = 0; |
1614 int dupos = 0; | |
1607 struct dict_object * new = NULL; | 1615 struct dict_object * new = NULL; |
1608 struct dict_object * vendor = NULL; | 1616 struct dict_object * vendor = NULL; |
1609 struct dict_object * locref = NULL; | 1617 struct dict_object * locref = NULL; |
1610 | 1618 |
1611 TRACE_ENTRY("%p %d(%s) %p %p %p", dict, type, dict_obj_info[CHECK_TYPE(type) ? type : 0].name, data, parent, ref); | 1619 TRACE_ENTRY("%p %d(%s) %p %p %p", dict, type, dict_obj_info[CHECK_TYPE(type) ? type : 0].name, data, parent, ref); |
1652 | 1660 |
1653 /* For COMMAND object, check that the 'R' flag is fixed */ | 1661 /* For COMMAND object, check that the 'R' flag is fixed */ |
1654 if (type == DICT_COMMAND) { | 1662 if (type == DICT_COMMAND) { |
1655 CHECK_PARAMS_DO( ((struct dict_cmd_data *)data)->cmd_flag_mask & CMD_FLAG_REQUEST, goto error_param ); | 1663 CHECK_PARAMS_DO( ((struct dict_cmd_data *)data)->cmd_flag_mask & CMD_FLAG_REQUEST, goto error_param ); |
1656 } | 1664 } |
1665 | |
1666 /* For ENUMVAL object, check if the parent type is an OctetString */ | |
1667 if (type == DICT_ENUMVAL) { | |
1668 if (parent->data.type.type_base == AVP_TYPE_OCTETSTRING) | |
1669 dupos = 1; | |
1670 } | |
1657 | 1671 |
1658 /* We have to check that the new values are not equal to the sentinels */ | 1672 /* We have to check that the new values are not equal to the sentinels */ |
1659 if (type == DICT_VENDOR) { | 1673 if (type == DICT_VENDOR) { |
1660 CHECK_PARAMS_DO( ((struct dict_vendor_data *)data)->vendor_id != 0, goto error_param ); | 1674 CHECK_PARAMS_DO( ((struct dict_vendor_data *)data)->vendor_id != 0, goto error_param ); |
1661 } | 1675 } |
1666 /* Parameters are valid, create the new object */ | 1680 /* Parameters are valid, create the new object */ |
1667 CHECK_MALLOC( new = malloc(sizeof(struct dict_object)) ); | 1681 CHECK_MALLOC( new = malloc(sizeof(struct dict_object)) ); |
1668 | 1682 |
1669 /* Initialize the data of the new object */ | 1683 /* Initialize the data of the new object */ |
1670 init_object(new, type); | 1684 init_object(new, type); |
1671 init_object_data(new, data, type); | 1685 init_object_data(new, data, type, dupos); |
1672 new->dico = dict; | 1686 new->dico = dict; |
1673 new->parent = parent; | 1687 new->parent = parent; |
1674 | 1688 |
1675 /* We will change the dictionary => acquire the write lock */ | 1689 /* We will change the dictionary => acquire the write lock */ |
1676 CHECK_POSIX_DO( ret = pthread_rwlock_wrlock(&dict->dict_lock), goto error_free ); | 1690 CHECK_POSIX_DO( ret = pthread_rwlock_wrlock(&dict->dict_lock), goto error_free ); |