diff options
-rw-r--r-- | bin/rdsquashfs/dump_xattrs.c | 6 | ||||
-rw-r--r-- | bin/rdsquashfs/restore_fstree.c | 6 | ||||
-rw-r--r-- | bin/rdsquashfs/stat.c | 2 | ||||
-rw-r--r-- | bin/sqfs2tar/xattr.c | 6 | ||||
-rw-r--r-- | extras/browse.c | 20 | ||||
-rw-r--r-- | extras/mk42sqfs.c | 2 | ||||
-rw-r--r-- | extras/mknastyfs.c | 2 | ||||
-rw-r--r-- | include/sqfs/data_reader.h | 4 | ||||
-rw-r--r-- | include/sqfs/dir_reader.h | 8 | ||||
-rw-r--r-- | include/sqfs/inode.h | 3 | ||||
-rw-r--r-- | include/sqfs/meta_reader.h | 4 | ||||
-rw-r--r-- | include/sqfs/predef.h | 43 | ||||
-rw-r--r-- | include/sqfs/xattr_reader.h | 4 | ||||
-rw-r--r-- | lib/sqfs/Makemodule.am | 1 | ||||
-rw-r--r-- | lib/sqfs/misc.c | 17 |
15 files changed, 95 insertions, 33 deletions
diff --git a/bin/rdsquashfs/dump_xattrs.c b/bin/rdsquashfs/dump_xattrs.c index 93b0b01..9dbe437 100644 --- a/bin/rdsquashfs/dump_xattrs.c +++ b/bin/rdsquashfs/dump_xattrs.c @@ -95,7 +95,7 @@ int dump_xattrs(sqfs_xattr_reader_t *xattr, const sqfs_inode_generic_t *inode) if (sqfs_xattr_reader_read_value(xattr, key, &value)) { fputs("Error reading xattr value\n", stderr); - free(key); + sqfs_free(key); return -1; } @@ -112,8 +112,8 @@ int dump_xattrs(sqfs_xattr_reader_t *xattr, const sqfs_inode_generic_t *inode) printf("\n"); } - free(key); - free(value); + sqfs_free(key); + sqfs_free(value); } return 0; diff --git a/bin/rdsquashfs/restore_fstree.c b/bin/rdsquashfs/restore_fstree.c index 3d536b6..57582c2 100644 --- a/bin/rdsquashfs/restore_fstree.c +++ b/bin/rdsquashfs/restore_fstree.c @@ -188,7 +188,7 @@ static int set_xattr(const char *path, sqfs_xattr_reader_t *xattr, if (sqfs_xattr_reader_read_value(xattr, key, &value)) { fputs("Error reading xattr value\n", stderr); - free(key); + sqfs_free(key); return -1; } @@ -199,8 +199,8 @@ static int set_xattr(const char *path, sqfs_xattr_reader_t *xattr, key->key, path, strerror(errno)); } - free(key); - free(value); + sqfs_free(key); + sqfs_free(value); if (ret) return -1; } diff --git a/bin/rdsquashfs/stat.c b/bin/rdsquashfs/stat.c index 049baae..a5aab60 100644 --- a/bin/rdsquashfs/stat.c +++ b/bin/rdsquashfs/stat.c @@ -172,7 +172,7 @@ int stat_file(const sqfs_tree_node_t *node) idx->size + 1, idx->name, idx->start_block, idx->index); - free(idx); + sqfs_free(idx); } break; } diff --git a/bin/sqfs2tar/xattr.c b/bin/sqfs2tar/xattr.c index 9a9ec82..abec4fb 100644 --- a/bin/sqfs2tar/xattr.c +++ b/bin/sqfs2tar/xattr.c @@ -68,13 +68,13 @@ int get_xattrs(const char *name, const sqfs_inode_generic_t *inode, ret = sqfs_xattr_reader_read_value(xr, key, &value); if (ret) { sqfs_perror(name, "reading xattr value", ret); - free(key); + sqfs_free(key); goto fail; } ent = mkxattr(key, value); - free(key); - free(value); + sqfs_free(key); + sqfs_free(value); if (ent == NULL) goto fail; diff --git a/extras/browse.c b/extras/browse.c index 86ce788..8b96c15 100644 --- a/extras/browse.c +++ b/extras/browse.c @@ -70,12 +70,12 @@ static void list_directory(const char *dirname) sqfs_dir_reader_get_root_inode(dr, &root); ret = sqfs_dir_reader_find_by_path(dr, root, dirname, &inode); - free(root); + sqfs_free(root); if (ret) goto fail_resolve; ret = sqfs_dir_reader_open_dir(dr, inode, 0); - free(inode); + sqfs_free(inode); if (ret) goto fail_open; } else { @@ -85,7 +85,7 @@ static void list_directory(const char *dirname) goto fail_resolve; ret = sqfs_dir_reader_open_dir(dr, inode, 0); - free(inode); + sqfs_free(inode); if (ret) goto fail_open; } @@ -102,7 +102,7 @@ static void list_directory(const char *dirname) } len = ent->size + 1; - free(ent); + sqfs_free(ent); } col_count = 79 / (max_len + 1); @@ -148,7 +148,7 @@ static void list_directory(const char *dirname) printf("%.*s", ent->size + 1, ent->name); fputs("\033[0m", stdout); - free(ent); + sqfs_free(ent); ++i; if (i == col_count) { @@ -231,7 +231,7 @@ static void stat_cmd(const char *filename) if (*filename == '/') { sqfs_dir_reader_get_root_inode(dr, &root); ret = sqfs_dir_reader_find_by_path(dr, root, filename, &inode); - free(root); + sqfs_free(root); if (ret) goto fail_resolve; } else { @@ -398,12 +398,12 @@ static void stat_cmd(const char *filename) printf("\tSize: %u\n", idx->size + 1); printf("\tEntry: %.*s\n\n", idx->size + 1, idx->name); - free(idx); + sqfs_free(idx); } break; } - free(inode); + sqfs_free(inode); return; fail_resolve: printf("Error resolving '%s', error code %d\n", filename, ret); @@ -429,7 +429,7 @@ static void cat_cmd(const char *filename) if (*filename == '/') { sqfs_dir_reader_get_root_inode(dr, &root); ret = sqfs_dir_reader_find_by_path(dr, root, filename, &inode); - free(root); + sqfs_free(root); } else { ret = sqfs_dir_reader_find_by_path(dr, working_dir, filename, &inode); @@ -459,7 +459,7 @@ static void cat_cmd(const char *filename) offset += diff; } - free(inode); + sqfs_free(inode); } /*****************************************************************************/ diff --git a/extras/mk42sqfs.c b/extras/mk42sqfs.c index 92323e0..08dffe6 100644 --- a/extras/mk42sqfs.c +++ b/extras/mk42sqfs.c @@ -167,7 +167,7 @@ int main(void) sqfs_meta_writer_get_position(inode_m, &block_start, &offset); super.root_inode_ref = (block_start << 16) | offset; sqfs_meta_writer_write_inode(inode_m, inode); - free(inode); + sqfs_free(inode); /* flush the meta data to the file */ sqfs_meta_writer_flush(inode_m); diff --git a/extras/mknastyfs.c b/extras/mknastyfs.c index daadf37..20074d3 100644 --- a/extras/mknastyfs.c +++ b/extras/mknastyfs.c @@ -146,7 +146,7 @@ int main(void) sqfs_meta_writer_get_position(inode_m, &block_start, &offset); super.root_inode_ref = (block_start << 16) | offset; sqfs_meta_writer_write_inode(inode_m, inode); - free(inode); + sqfs_free(inode); /* flush the meta data to the file */ sqfs_meta_writer_flush(inode_m); diff --git a/include/sqfs/data_reader.h b/include/sqfs/data_reader.h index c967a70..29077b7 100644 --- a/include/sqfs/data_reader.h +++ b/include/sqfs/data_reader.h @@ -94,7 +94,7 @@ SQFS_API int sqfs_data_reader_load_fragment_table(sqfs_data_reader_t *data, * @param inode A pointer to the inode describing the file. * @param size Returns the size of the data read. * @param out Returns a pointer to the raw data that must be - * released using free. + * released using @ref sqfs_free. * * @return Zero on succcess, an @ref SQFS_ERROR value on failure. */ @@ -112,7 +112,7 @@ SQFS_API int sqfs_data_reader_get_fragment(sqfs_data_reader_t *data, * @param index The block index in the inodes block list. * @param size Returns the size of the data read. * @param out Returns a pointer to the raw data that must be - * released using free. + * released using @ref sqfs_free. * * @return Zero on succcess, an @ref SQFS_ERROR value on failure. */ diff --git a/include/sqfs/dir_reader.h b/include/sqfs/dir_reader.h index cf9f2a1..3bef7e3 100644 --- a/include/sqfs/dir_reader.h +++ b/include/sqfs/dir_reader.h @@ -231,7 +231,7 @@ SQFS_API int sqfs_dir_reader_find(sqfs_dir_reader_t *rd, const char *name); * * @param rd A pointer to a directory reader. * @param out Returns a pointer to a directory entry on success that can be - * freed with a single free call. + * freed with a single @ref sqfs_free call. * * @return Zero on success, an @ref SQFS_ERROR value on failure, a positive * number if the end of the current directory listing has been reached. @@ -246,7 +246,7 @@ SQFS_API int sqfs_dir_reader_read(sqfs_dir_reader_t *rd, * * @param rd A pointer to a directory reader. * @param out Returns a pointer to a generic inode that can be freed with a - * single free call. + * single @ref sqfs_free call. * * @return Zero on success, an @ref SQFS_ERROR value on failure. */ @@ -260,7 +260,7 @@ SQFS_API int sqfs_dir_reader_get_inode(sqfs_dir_reader_t *rd, * * @param rd A pointer to a directory reader. * @param out Returns a pointer to a generic inode that can be freed with a - * single free call. + * single @ref sqfs_free call. * * @return Zero on success, an @ref SQFS_ERROR value on failure. */ @@ -280,7 +280,7 @@ SQFS_API int sqfs_dir_reader_get_root_inode(sqfs_dir_reader_t *rd, * be used to separate path components. Resolving '.' or '..' is * not supported. * @param out Returns a pointer to a generic inode that can be freed with a - * single free call. + * single @ref sqfs_free call. * * @return Zero on success, an @ref SQFS_ERROR value on failure. */ diff --git a/include/sqfs/inode.h b/include/sqfs/inode.h index 5359b54..0bc33db 100644 --- a/include/sqfs/inode.h +++ b/include/sqfs/inode.h @@ -718,7 +718,8 @@ SQFS_API int sqfs_inode_get_file_block_start(const sqfs_inode_generic_t *inode, * fiddles the raw data out into a propperly aligned, external structure. * * @param inode A pointer to an inode. - * @param out Returns the index entry. Can be freed with a single free call. + * @param out Returns the index entry. Can be freed with a single + * @ref sqfs_free call. * @param index An index value between 0 and inodex_count. * * @return Zero on success, @ref SQFS_ERROR_OUT_OF_BOUNDS if the given index diff --git a/include/sqfs/meta_reader.h b/include/sqfs/meta_reader.h index bac1808..e0dc186 100644 --- a/include/sqfs/meta_reader.h +++ b/include/sqfs/meta_reader.h @@ -145,7 +145,7 @@ SQFS_API int sqfs_meta_reader_read_dir_header(sqfs_meta_reader_t *m, * * @param m A pointer to a meta data reader. * @param ent Returns a pointer to a directory entry. Can be released with a - * single free() call. + * single @ref sqfs_free call. * * @return Zero on success, an @ref SQFS_ERROR value on failure. */ @@ -167,7 +167,7 @@ SQFS_API int sqfs_meta_reader_read_dir_ent(sqfs_meta_reader_t *m, * @param offset A byte offset within the uncompressed block where the * inode is. * @param out Returns a pointer to an inode. Can be released with a - * single free() call. + * single @ref sqfs_free call. * * @return Zero on success, an @ref SQFS_ERROR value on failure. */ diff --git a/include/sqfs/predef.h b/include/sqfs/predef.h index 55ccc86..3254186 100644 --- a/include/sqfs/predef.h +++ b/include/sqfs/predef.h @@ -156,4 +156,47 @@ static SQFS_INLINE void *sqfs_copy(const void *obj) return NULL; } +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Free a block of memory created by the squashfs library + * + * Some objects in the squashfs library allocate temporary chunks of memory + * and return pointers to them, with the expectation that the user takes care + * of freeing them memory again. + * + * In the past this worked without hitches, because most sane operating systems + * have a single, global C library that everything is linked against. On + * systems like Windows that have a huge fragmentation of runtime libraries + * this fails, because the library and application can easily end up linked + * against different runtime libraries, making it impossible for the program + * to free the memory. + * + * To re-create the same situation on Linux, one would have to link a program + * and the squashfs library dynamically, while linking at least one of them + * statically against the C runtime, or intentionally linking against two + * different runtimes. + * + * This function mitigates the arising problem by exposing the free() function + * of the libraries runtime to the application, so it can propperly release + * memory again to the correct heap. + * + * To maintain API/ABI compatibillity, it is guaranteed that for all versions + * of libsquashfs with major version 1, this function does nothing other than + * call free() on the C runtime that the library was linked against. If just + * calling free() works on your system, it will continue to work, and older + * application will continue to work with newer versions of libsquashfs 1.x. + * Going forward, new applications using libsquashfs should use this function + * instead for better portabillity. + * + * @param ptr A pointer to a memory block returned by a libsquashfs function. + */ +SQFS_API void sqfs_free(void *ptr); + +#ifdef __cplusplus +} +#endif + #endif /* SQFS_PREDEF_H */ diff --git a/include/sqfs/xattr_reader.h b/include/sqfs/xattr_reader.h index 8294bd8..a0242fb 100644 --- a/include/sqfs/xattr_reader.h +++ b/include/sqfs/xattr_reader.h @@ -160,7 +160,7 @@ SQFS_API int sqfs_xattr_reader_seek_kv(sqfs_xattr_reader_t *xr, * * @param xr A pointer to an xattr reader instance * @param key_out Used to return the decoded key. The underlying memory can be - * released using a single free() call. + * released using a single @ref sqfs_free call. * * @return Zero on success, a negative @ref SQFS_ERROR value on failure. */ @@ -181,7 +181,7 @@ int sqfs_xattr_reader_read_key(sqfs_xattr_reader_t *xr, * @param xr A pointer to an xattr reader instance. * @param key A pointer to the decoded key object. * @param val_out Used to return the decoded value. The underlying memory can - * be released using a single free() call. + * be released using a single @ref sqfs_free call. * * @return Zero on success, a negative @ref SQFS_ERROR value on failure. */ diff --git a/lib/sqfs/Makemodule.am b/lib/sqfs/Makemodule.am index d6b392e..df6e3ce 100644 --- a/lib/sqfs/Makemodule.am +++ b/lib/sqfs/Makemodule.am @@ -30,6 +30,7 @@ libsquashfs_la_SOURCES += lib/sqfs/block_processor/block_processor.c libsquashfs_la_SOURCES += lib/sqfs/block_processor/backend.c libsquashfs_la_SOURCES += lib/sqfs/frag_table.c include/sqfs/frag_table.h libsquashfs_la_SOURCES += lib/sqfs/block_writer.c include/sqfs/block_writer.h +libsquashfs_la_SOURCES += lib/sqfs/misc.c libsquashfs_la_CPPFLAGS = $(AM_CPPFLAGS) libsquashfs_la_LDFLAGS = $(AM_LDFLAGS) -version-info $(LIBSQUASHFS_SO_VERSION) libsquashfs_la_CFLAGS = $(AM_CFLAGS) $(PTHREAD_CFLAGS) $(ZLIB_CFLAGS) diff --git a/lib/sqfs/misc.c b/lib/sqfs/misc.c new file mode 100644 index 0000000..74a4203 --- /dev/null +++ b/lib/sqfs/misc.c @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: LGPL-3.0-or-later */ +/* + * misc.c + * + * Copyright (C) 2021 David Oberhollenzer <goliath@infraroot.at> + */ +#define SQFS_BUILDING_DLL +#include "config.h" + +#include "sqfs/predef.h" + +#include <stdlib.h> + +void sqfs_free(void *ptr) +{ + free(ptr); +} |