X-Git-Url: https://wimlib.net/git/?p=wimlib;a=blobdiff_plain;f=src%2Fxml.c;h=72eca4b378b80d8a4320eee177e30d9ae92da536;hp=c4382d430f793462cc4e26120dd560c95decd033;hb=50ae56edcc3938f5183ddfc8910de2df5774eaf6;hpb=670a54f5de37bff02c49f37d690b26654cf7fa1d diff --git a/src/xml.c b/src/xml.c index c4382d43..72eca4b3 100644 --- a/src/xml.c +++ b/src/xml.c @@ -78,11 +78,10 @@ struct image_info { tchar *display_name; tchar *display_description; tchar *flags; - struct wim_lookup_table *lookup_table; /* Temporary field only */ }; struct xml_string_spec { - const utf8char *name; + const char *name; size_t offset; }; @@ -126,7 +125,7 @@ get_arch(int arch) return T("x86_64"); /* XXX Are there other arch values? */ default: - return NULL; + return T("unknown"); } } @@ -149,34 +148,36 @@ node_is_text(xmlNode *node) } static inline bool -node_name_is(xmlNode *node, const utf8char *name) +node_name_is(xmlNode *node, const char *name) { /* For now, both upper case and lower case element names are accepted. */ return strcasecmp((const char *)node->name, name) == 0; } -/* Finds the text node that is a child of an element node and returns its - * content converted to a 64-bit unsigned integer. Returns 0 if no text node is - * found. */ static u64 -node_get_u64(const xmlNode *u64_node) +node_get_number(const xmlNode *u64_node, int base) { xmlNode *child; for_node_child(u64_node, child) if (node_is_text(child)) - return strtoull((const char *)child->content, NULL, 10); + return strtoull(child->content, NULL, base); return 0; } +/* Finds the text node that is a child of an element node and returns its + * content converted to a 64-bit unsigned integer. Returns 0 if no text node is + * found. */ +static u64 +node_get_u64(const xmlNode *u64_node) +{ + return node_get_number(u64_node, 10); +} + /* Like node_get_u64(), but expects a number in base 16. */ static u64 node_get_hex_u64(const xmlNode *u64_node) { - xmlNode *child; - for_node_child(u64_node, child) - if (node_is_text(child)) - return strtoull(child->content, NULL, 16); - return 0; + return node_get_number(u64_node, 16); } static int @@ -529,7 +530,7 @@ print_windows_info(const struct windows_info *windows_info) const struct windows_version *windows_version; tprintf(T("Architecture: %"TS"\n"), - get_arch(windows_info->arch) ?: T("unknown")); + get_arch(windows_info->arch)); if (windows_info->product_name) { tprintf(T("Product Name: %"TS"\n"), @@ -597,7 +598,7 @@ xml_write_string(xmlTextWriter *writer, const char *name, const tchar *tstr) { if (tstr) { - utf8char *utf8_str; + char *utf8_str; int rc = tstr_to_utf8_simple(tstr, &utf8_str); if (rc) return rc; @@ -745,7 +746,7 @@ xml_write_windows_info(xmlTextWriter *writer, /* Writes a time element to the XML document being constructed in memory. */ static int -xml_write_time(xmlTextWriter *writer, const utf8char *element_name, u64 time) +xml_write_time(xmlTextWriter *writer, const char *element_name, u64 time) { int rc; rc = xmlTextWriterStartElement(writer, element_name); @@ -813,7 +814,7 @@ xml_write_image_info(xmlTextWriter *writer, const struct image_info *image_info) if (image_info->windows_info_exists) { rc = xml_write_windows_info(writer, &image_info->windows_info); - if (rc < 0) + if (rc) return rc; } @@ -856,6 +857,8 @@ clone_windows_info(const struct windows_info *old, struct windows_info *new) ret = dup_strings_from_specs(old, new, windows_info_xml_string_specs, ARRAY_LEN(windows_info_xml_string_specs)); + if (ret) + return ret; if (old->languages) { new->languages = CALLOC(old->num_languages, sizeof(new->languages[0])); @@ -982,9 +985,9 @@ xml_delete_image(struct wim_info **wim_info_p, int image) { struct wim_info *wim_info; - DEBUG("Deleting image %d from the XML data.", image); - wim_info = *wim_info_p; + wimlib_assert(image >= 1 && image <= wim_info->num_images); + DEBUG("Deleting image %d from the XML data.", image); destroy_image_info(&wim_info->images[image - 1]); @@ -1029,7 +1032,6 @@ static int calculate_dentry_statistics(struct wim_dentry *dentry, void *arg) { struct image_info *info = arg; - struct wim_lookup_table *lookup_table = info->lookup_table; const struct wim_inode *inode = dentry->d_inode; struct wim_lookup_table_entry *lte; @@ -1076,7 +1078,7 @@ calculate_dentry_statistics(struct wim_dentry *dentry, void *arg) * link bytes", and this size is multiplied by the link count (NOT one * less than the link count). */ - lte = inode_unnamed_lte(inode, info->lookup_table); + lte = inode_unnamed_lte_resolved(inode); if (lte) { info->total_bytes += wim_resource_size(lte); if (!dentry_is_first_in_inode(dentry)) @@ -1086,7 +1088,7 @@ calculate_dentry_statistics(struct wim_dentry *dentry, void *arg) if (inode->i_nlink >= 2 && dentry_is_first_in_inode(dentry)) { for (unsigned i = 0; i < inode->i_num_ads; i++) { if (inode->i_ads_entries[i].stream_name_nbytes) { - lte = inode_stream_lte(inode, i + 1, lookup_table); + lte = inode_stream_lte_resolved(inode, i + 1); if (lte) { info->hard_link_bytes += inode->i_nlink * wim_resource_size(lte); @@ -1118,8 +1120,7 @@ xml_update_image_info(WIMStruct *w, int image) image_info->total_bytes = 0; image_info->hard_link_bytes = 0; - image_info->lookup_table = w->lookup_table; - for_dentry_in_tree(w->image_metadata[image - 1].root_dentry, + for_dentry_in_tree(w->image_metadata[image - 1]->root_dentry, calculate_dentry_statistics, image_info); image_info->last_modification_time = get_wim_timestamp(); @@ -1236,7 +1237,7 @@ libxml_global_cleanup() */ int read_xml_data(FILE *fp, const struct resource_entry *res_entry, - utf16lechar **xml_data_ret, struct wim_info **info_ret) + struct wim_info **info_ret) { utf16lechar *xml_data; xmlDoc *doc; @@ -1266,7 +1267,7 @@ read_xml_data(FILE *fp, const struct resource_entry *res_entry, ret = read_uncompressed_resource(fp, res_entry->offset, res_entry->size, xml_data); - if (ret != 0) + if (ret) goto out_free_xml_data; /* Null-terminate just in case */ @@ -1295,18 +1296,11 @@ read_xml_data(FILE *fp, const struct resource_entry *res_entry, } if (!node_is_element(root) || !node_name_is(root, "WIM")) { - ERROR("Expected for the root XML element (found <%s>)", - root->name); + ERROR("Expected for the root XML element"); ret = WIMLIB_ERR_XML; goto out_free_doc; } - ret = xml_read_wim_info(root, info_ret); - if (ret != 0) - goto out_free_doc; - - *xml_data_ret = xml_data; - xml_data = NULL; out_free_doc: DEBUG("Freeing XML tree."); xmlFreeDoc(doc); @@ -1482,7 +1476,7 @@ wimlib_image_name_in_use(const WIMStruct *w, const tchar *name) if (!name || !*name) return false; for (int i = 1; i <= w->hdr.image_count; i++) - if (tstrcmp(w->wim_info->images[i - 1].name, name) == 0) + if (!tstrcmp(w->wim_info->images[i - 1].name, name)) return true; return false; } @@ -1492,16 +1486,33 @@ wimlib_image_name_in_use(const WIMStruct *w, const tchar *name) WIMLIBAPI int wimlib_extract_xml_data(WIMStruct *w, FILE *fp) { - size_t bytes_written; + size_t size; + void *buf; + int ret; - if (!w->xml_data) - return WIMLIB_ERR_INVALID_PARAM; - bytes_written = fwrite(w->xml_data, 1, w->hdr.xml_res_entry.size, fp); - if (bytes_written != w->hdr.xml_res_entry.size) { + size = w->hdr.xml_res_entry.size; + if (sizeof(size_t) < sizeof(u64)) + if (size != w->hdr.xml_res_entry.size) + return WIMLIB_ERR_INVALID_PARAM; + + buf = MALLOC(size); + if (!buf) + return WIMLIB_ERR_NOMEM; + + ret = read_uncompressed_resource(w->fp, w->hdr.xml_res_entry.offset, + size, buf); + if (ret) + goto out_free_buf; + + if (fwrite(buf, 1, size, fp) != size) { ERROR_WITH_ERRNO("Failed to extract XML data"); - return WIMLIB_ERR_WRITE; + ret = WIMLIB_ERR_WRITE; + } else { + ret = 0; } - return 0; +out_free_buf: + FREE(buf); + return ret; } /* Sets the name of an image in the WIM. */