static uint32 data_element_get_size (unsigned des, const uint8 **buf, uint32 *len, void (*handle_element) (unsigned type, const uint8 *buf, uint32 len)) { uint32 size; #define DATA_ELEMENT_A_BAD_SIZE ((uint32) -1) switch (des) { case DATA_ELEMENT_SIZE_A8: if (*len < 1) { data_element_errno = DATA_ELEMENT_ERROR_TRUNCATED; handle_element (DATA_ELEMENT_ERROR_TRUNCATED, NULL, 0); return DATA_ELEMENT_A_BAD_SIZE; } ++*buf; --*len; *len -= 1; size = *(*buf)++; return size; case DATA_ELEMENT_SIZE_A16: if (*len < 2) { data_element_errno = DATA_ELEMENT_ERROR_TRUNCATED; handle_element (DATA_ELEMENT_ERROR_TRUNCATED, NULL, 1); return DATA_ELEMENT_A_BAD_SIZE; } ++*buf; --*len; *len -= 2; size = *(*buf)++; size <<= 8; size |= *(*buf)++; return size; case DATA_ELEMENT_SIZE_A32: if (*len < 4) { data_element_errno = DATA_ELEMENT_ERROR_TRUNCATED; handle_element (DATA_ELEMENT_ERROR_TRUNCATED, NULL, 2); return DATA_ELEMENT_A_BAD_SIZE; } ++*buf; --*len; *len -= 4; size = *(*buf)++; size <<= 8; size |= *(*buf)++; size <<= 8; size |= *(*buf)++; size <<= 8; size |= *(*buf)++; return size; } data_element_errno = DATA_ELEMENT_ERROR_INTERNAL; handle_element (DATA_ELEMENT_ERROR_INTERNAL, NULL, 0); return DATA_ELEMENT_A_BAD_SIZE; }
static void on_end_element(GMarkupParseContext *context, const gchar *element_name, gpointer user_data, GError **error) { debug_printf("on_end_element %s\n", element_name); if (strcmp(element_name, "fragment") == 0) { } else if (strcmp(element_name, "vertex") == 0) { } else { return; } parse_data *data = user_data; data->buffer[data->length] = 0; if (data->error) { } else { debug_printf("%s\n", data->buffer); handle_element(data, element_name, data->buffer); } if (data->filter) { g_free(data->filter); data->filter = NULL; } }
static void data_element_decode_internal (const uint8 **buf, uint32 *len, void (*handle_element) (unsigned type, const uint8 *buf, uint32 len)) { unsigned des, det; uint32 size; if (*len == 0) { data_element_errno = DATA_ELEMENT_ERROR_TRUNCATED; handle_element (DATA_ELEMENT_ERROR_TRUNCATED, NULL, 3); } else { det = DATA_ELEMENT_TYPE (**buf); des = DATA_ELEMENT_SIZE (**buf); switch (det) { case DATA_ELEMENT_TYPE_NIL: if (des != DATA_ELEMENT_SIZE_1) { data_element_errno = DATA_ELEMENT_ERROR_INVALID; handle_element (DATA_ELEMENT_ERROR_INVALID, NULL, 0); } else { ++*buf; --*len; handle_element (det, NULL, 0); } break; case DATA_ELEMENT_TYPE_UUID: if (des != DATA_ELEMENT_SIZE_2 && des != DATA_ELEMENT_SIZE_4 && des != DATA_ELEMENT_SIZE_16) { data_element_errno = DATA_ELEMENT_ERROR_INVALID; handle_element (DATA_ELEMENT_ERROR_INVALID, NULL, 0); break; } /* Deliberate fall-through */ case DATA_ELEMENT_TYPE_UINT: case DATA_ELEMENT_TYPE_INT: if (des > DATA_ELEMENT_SIZE_16) { data_element_errno = DATA_ELEMENT_ERROR_INVALID; handle_element (DATA_ELEMENT_ERROR_INVALID, NULL, 0); } else { size = 1 << des; if (*len < 1 + size) { data_element_errno = DATA_ELEMENT_ERROR_TRUNCATED; handle_element (DATA_ELEMENT_ERROR_TRUNCATED, NULL, 4); } else { ++*buf; --*len; handle_element (det, *buf, size); *buf += size; *len -= size; } } break; case DATA_ELEMENT_TYPE_TEXT: case DATA_ELEMENT_TYPE_URL: if (des < DATA_ELEMENT_SIZE_A8) { data_element_errno = DATA_ELEMENT_ERROR_INVALID; handle_element (DATA_ELEMENT_ERROR_INVALID, NULL, 0); } else { uint32 save_len = *len; if ((size = data_element_get_size (des, buf, len, handle_element)) != DATA_ELEMENT_A_BAD_SIZE) { if (*len < size) { *buf -= save_len - *len; *len = save_len; data_element_errno = DATA_ELEMENT_ERROR_TRUNCATED; handle_element (DATA_ELEMENT_ERROR_TRUNCATED, NULL, 5); } else { handle_element (det, *buf, size); *buf += size; *len -= size; } } } break; case DATA_ELEMENT_TYPE_BOOL: if (des != DATA_ELEMENT_SIZE_1) { data_element_errno = DATA_ELEMENT_ERROR_INVALID; handle_element (DATA_ELEMENT_ERROR_INVALID, NULL, 0); } else { if (*len < 2) { data_element_errno = DATA_ELEMENT_ERROR_TRUNCATED; handle_element (DATA_ELEMENT_ERROR_TRUNCATED, NULL, 6); } else { ++*buf; --*len; handle_element (det, *buf, 1); ++*buf; --*len; } } break; case DATA_ELEMENT_TYPE_SEQ: case DATA_ELEMENT_TYPE_ALT: if (des < DATA_ELEMENT_SIZE_A8) { data_element_errno = DATA_ELEMENT_ERROR_INVALID; handle_element (DATA_ELEMENT_ERROR_INVALID, NULL, 0); } else { uint32 save_len = *len; if ((size = data_element_get_size (des, buf, len, handle_element)) != DATA_ELEMENT_A_BAD_SIZE) { if (*len < size) { *buf -= save_len - *len; *len = save_len; data_element_errno = DATA_ELEMENT_ERROR_TRUNCATED; handle_element (DATA_ELEMENT_ERROR_TRUNCATED, NULL, 7); } else { save_len = *len; handle_element (det | DATA_ELEMENT_TYPE_START, NULL, 0); while (save_len - *len != size) { data_element_decode (buf, len, handle_element); if (data_element_errno) { break; } if (save_len - *len != size) { handle_element (det | DATA_ELEMENT_TYPE_SEPARATOR, NULL, 0); } } handle_element (det | DATA_ELEMENT_TYPE_END, NULL, 0); } } } break; default: data_element_errno = DATA_ELEMENT_ERROR_INVALID; handle_element (DATA_ELEMENT_ERROR_INVALID, NULL, 0); break; } } }
CInterfaceDefinition *CInterfaceDefinitionLoader::load( const unsigned char &buffer, unsigned int buffer_size ) { assert( !m_interface_definition && !m_reader && m_element_path.empty() ); m_interface_definition = new CInterfaceDefinition; xmlInitParser(); m_reader = xmlReaderForMemory( (char *) &buffer, buffer_size, NULL, NULL, 0 ); if( !m_reader ) { INTEGRA_TRACE_ERROR << "unable to read file"; cleanup(); return NULL; } int depth = -1; bool handled_element_content = false; char *inner_xml = NULL; while( xmlTextReaderRead( m_reader ) ) { switch( xmlTextReaderNodeType( m_reader ) ) { case XML_READER_TYPE_TEXT: { char *element_value = ( char * ) xmlTextReaderValue( m_reader ); if( handle_element_value( element_value ) != CError::SUCCESS ) { xmlFree( element_value ); cleanup(); return NULL; } xmlFree( element_value ); handled_element_content = true; store_map_entries(); } break; case XML_READER_TYPE_ELEMENT: { const char *element_name = ( const char * ) xmlTextReaderConstName( m_reader ); int new_depth = xmlTextReaderDepth( m_reader ); while( depth >= new_depth ) { pop_element_name(); depth--; } if( depth < new_depth ) { push_element_name( element_name ); depth++; } assert( depth == new_depth ); if( handle_element() != CError::SUCCESS ) { cleanup(); return NULL; } if( xmlTextReaderHasAttributes( m_reader ) ) { if( handle_element_attributes() != CError::SUCCESS ) { cleanup(); return NULL; } } if( xmlTextReaderIsEmptyElement( m_reader ) ) { handle_element_value( "" ); handled_element_content = true; } else { handled_element_content = false; inner_xml = ( char * ) xmlTextReaderReadInnerXml( m_reader ); } } break; case XML_READER_TYPE_END_ELEMENT: if( !handled_element_content && inner_xml ) { handle_element_value( inner_xml ); } if( inner_xml ) { xmlFree( inner_xml ); inner_xml = NULL; } handled_element_content = true; break; default: break; } } CError CError = do_sanity_check(); if( CError != CError::SUCCESS ) { INTEGRA_TRACE_ERROR << "sanity check failed"; cleanup(); return NULL; } m_interface_definition->propagate_defaults(); INTEGRA_TRACE_VERBOSE << "Loaded ok: " << m_interface_definition->get_interface_info().get_name(); CInterfaceDefinition *loaded_interface = m_interface_definition; m_interface_definition = NULL; cleanup(); return loaded_interface; }