aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bin/rdsquashfs/dump_xattrs.c6
-rw-r--r--bin/rdsquashfs/restore_fstree.c6
-rw-r--r--bin/rdsquashfs/stat.c2
-rw-r--r--bin/sqfs2tar/xattr.c6
-rw-r--r--extras/browse.c20
-rw-r--r--extras/mk42sqfs.c2
-rw-r--r--extras/mknastyfs.c2
-rw-r--r--include/sqfs/data_reader.h4
-rw-r--r--include/sqfs/dir_reader.h8
-rw-r--r--include/sqfs/inode.h3
-rw-r--r--include/sqfs/meta_reader.h4
-rw-r--r--include/sqfs/predef.h43
-rw-r--r--include/sqfs/xattr_reader.h4
-rw-r--r--lib/sqfs/Makemodule.am1
-rw-r--r--lib/sqfs/misc.c17
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 fedb7a8..99f06e9 100644
--- a/lib/sqfs/Makemodule.am
+++ b/lib/sqfs/Makemodule.am
@@ -29,6 +29,7 @@ libsquashfs_la_SOURCES += lib/sqfs/block_processor/common.c
libsquashfs_la_SOURCES += lib/sqfs/block_processor/frontend.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);
+}