summaryrefslogtreecommitdiff
path: root/include/sqfs
diff options
context:
space:
mode:
authorDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2021-04-08 12:04:33 +0200
committerDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2021-04-08 12:04:33 +0200
commita3739ada111bf4e36ae7576b24176d1db55e1365 (patch)
treea7c0eee1aacf91137c6f163a7dc301cf114125ff /include/sqfs
parent7c6c0c07dda1f44b930ee2dbb9451979b6a2cb83 (diff)
Fix: libsquashfs: add sqfs_free() function
On systems like Windows, the dynamic library and applications can easily end up being linked against different runtime libraries, so applications cannot be expected to be able to free() any malloc'd pointer that the library returns. This commit adds an sqfs_free function so the application can pass pointers back to the library to call the correct free() implementation. Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
Diffstat (limited to 'include/sqfs')
-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
6 files changed, 55 insertions, 11 deletions
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.
*/