static int mar_unpack(lua_State *L, const char* buf, size_t len, int *idx) { const char* p; p = buf; while (p - buf < len) { unpack_value(L, buf, len, &p, idx); unpack_value(L, buf, len, &p, idx); lua_settable(L, -3); } return 1; }
int tlv_unpack(tlv_t *tlv, uint8_t *packed, uint32_t sz) { if (NULL == tlv || NULL == packed || 0 == sz) { return -1; } uint8_t *p = packed; uint16_t id = 0, type = 0, length = 0; int b = 0; id = ntohs(GET16(p)); ADVANCE16P(p); type = ntohs(GET16(p)); ADVANCE16P(p); length = ntohs(GET16(p)); ADVANCE16P(p); if (length > sz) { ph_debug("not enough packed buf, length:%d sz:%d", length, sz); return -1; } b = unpack_value(type, id, p, length, tlv); return b; }
int unpack_array_values( byte *blob, void **array, int element_nref, char *description, ssize_t *offset, int (*unpack)( void *value, char typechar, ssize_t size, ssize_t *offset, byte *blob, cexception_t *ex ), cexception_t *ex ) { char *array_ptr; alloccell_t *blob_header; char *descr_ptr; ssize_t size, length, count, start; ssize_t element_size = element_nref > 0 ? REF_SIZE : sizeof(stackunion_t); char *count_str; char typechar; ssize_t i; assert( description ); if( !blob ) return 1; blob_header = ((alloccell_t*)blob) - 1; count = 0; descr_ptr = description; while( *description ) { if( description[0] != 'X' && description[0] != 'x' ) { if( isdigit( description[1] )) { strtol( description + 1, &count_str, 0 ); if( count_str && count_str[0] && isdigit( count_str[1] )) { count += strtol( count_str + 1, NULL, 0 ); } else { count ++; } } else if( description[1] != '\0' && isdigit( description[2] )) { count += strtol( description + 2, NULL, 0 ); } else { count ++; } } while( *description && *description != ',' ) description++; if( *description ) description++; } array_ptr = bcalloc_array( REF_SIZE, count, element_nref, ex ); BC_CHECK_PTR( array_ptr, ex ); *array = array_ptr; description = descr_ptr; start = 0; while( *description ) { size = count = 0; typechar = description[0]; if( isdigit( description[1] )) { if( description[0] != '\0' ) { size = strtol( description + 1, &count_str, 0 ); if( count_str && count_str[0] && isdigit( count_str[1] )) { count = strtol( count_str + 1, &description, 0 ); } else { count ++; } } } else if( description[1] != '\0' && isdigit( description[2] )) { count = strtol( description + 2, NULL, 0 ); } else { count ++; } if( count > 0 ) { if( size > 0 ) { if( blob_header->size < size * count + *offset ) { interpret_raise_exception_with_bcalloc_message ( /* err_code = */ -1, /* message = */ "attempting to unpack values past the end of a blob", /* module_id = */ 0, /* exception_id = */ SL_EXCEPTION_BLOB_OVERFLOW, ex ); return 0; } } if( typechar != 'X' && typechar != 'x' ) { for( i = 0; i < count; i ++ ) { if( unpack_value( array_ptr + (start + i)*element_size, typechar, size, offset, blob, unpack, ex ) == 0 ) { return 0; } } start += count; } else { if( size <= 0 ) { for( i = 0; i < count; i++ ) { length = strnlen( (char*)blob + *offset, blob_header->size - *offset ) + 1; *offset += length; } } else { *offset += size * count; } } } while( *description && *description != ',' ) description++; if( *description ) description++; } return 1; }