80 likes | 266 Views
Issue Escaped from Klocwork. Data Structure. typedef struct { hdr_t data_hdr ; /* place holder for header */ uniChar_t string[1]; /* place holder for string data */ } uniString_t ; struct _HEADER_STRUCT { …….; };
E N D
Data Structure • typedefstruct • { • hdr_tdata_hdr; /* place holder for header */ • uniChar_t string[1]; /* place holder for string data */ • } uniString_t; • struct_HEADER_STRUCT • { • …….; • }; • typedefstruct _HEADER_STRUCT BUF_HEADER; • typedefstruct _HEADER_STRUCT * BUF_PTR; • typedef BUF_HEADER hdr_t; • typedef UINT16 uniChar_t; • const unsigned char buf_footer[] = {‘A', ‘B', ‘C', 'D'}; • #define BUFSIZE(bs) ((sizeof(bs) > sizeof(hdr_t)) ? (sizeof(bs) - sizeof(hdr_t)) : 0)
Buffer Allocation • Function • BUF_PTR Get_Buf(UINT32 my_pool) • { • BUF_PTR bptr; • /* allocate memory, including buffer footer */ • bptr = (BUF_PTR)malloc(my_pool + sizeof(buf_footer) + sizeof(hdr_t)); • /* save the size of the buffer for Get_Buf_Size() */ • if (bptr != NULL) • { • memset( bptr, 0, my_pool + sizeof(buf_footer) + sizeof(hdr_t)); • /* Initialize the buffer with the specific header and footer*/ • ……. • } • ……. • return (bptr); • } • Usage • Allocate a buffer with size my_pool • The buffer consist of: Header (with size of hdr_t) Empty Buffer (with size of parameter my_pool) Footer (4 bytes)
Buffer Allocation Example: Allocate a buffer with structure uniString_t, the buffer length is MAX_LEN data_hdr string[0]; uniString_t **buff sizeof(hdr_t) string[1] string[2] … 2 bytes string[MAX_LEN]; (MAX_LEN+1) bytes MAX_LEN * 2 bytes ‘A’ ‘B’ typedef struct { hdr_t data_hdr; uniChar_t string[1]; } uniString_t; ‘C’ ‘D’ 4 bytes
String Copy • Function: • uniChar_t * uniStrncpy(uniChar_t *dst, const uniChar_t *src, INT32 n) • { • uniChar_t *anchor = dst; • /* copy string 2 over */ • while(n > 0 && (*(dst++) = *(src++)) != UNICODE_EOS) • { • --n; • } • /* make sure dst is null terminated */ • *dst = UNICODE_EOS; • return anchor; • } • Usage: • Copy n unicode characters (each character has 2 bytes) from buffer*src to buffer*dst. • It will always write the UNICODE_EOS in the end of the string ( the (n+1) position).
String Copy data_hdr data_hdr uniChar_t *dst string[0]; n * 2 bytes Or SRC_LEN *2 bytes string[1] … string[0]; string[1] string[2] … UNICODE_EOS string[n+2] … string[MAX_LEN]; uniChar_t *src ‘A’ string[MAX_LEN]; ‘B’ ‘C’ ‘A’ ‘D’ ‘B’ SRC_LEN * 2 bytes ‘C’ ‘D’ Prediction: n <= MAX_LEN UNICODE_EOS
Failure Mode • Failure Scenario: • void func (uniString_t** buff, uniChar_t* data) • { • UINT16 location = 0; • location = func1(data); • if(location != 0) • { • if(*buff == NULL) • { • /*allocate buffer*/ • *buff = (uniString_t *)Get_Buf(BUFSIZE(uniString_t) + MAX_LEN* sizeof(uniChar_t)); • memset((UINT8 *)(*buff)->string, 0, sizeof(uniChar_t)*(MAX_LEN + 1)); • } • uniStrncpy((*buff)->string, data, location); • } • Notes: • (*buff)->string[0] is the 1st unicode character of the allocated empty buffer; • The empty buffer size should be (1 + MAX_LEN); • The location may exceed the MAX_LEN. It may cause the memory damage when use uniStrncpy to copy the string. typedef struct { hdr_t data_hdr; uniChar_t string[1]; } uniString_t;
Failure Mode data_hdr data_hdr uniChar_t *dst string[0]; n * 2 bytes string[1] … string[0]; string[1] string[2] … string[n+2] … string[MAX_LEN]; ‘A’ string[MAX_LEN]; ‘B’ uniChar_t *src ‘C’ ‘D’ ‘N’ UNICODE_EOS ‘D’ Unexpected Case: n >MAX_LEN UNICODE_EOS