diff options
| author | Luca Boccassi <luca.boccassi@microsoft.com> | 2021-07-30 15:56:11 +0100 | 
|---|---|---|
| committer | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2022-03-30 22:31:30 +0200 | 
| commit | a0c0f38cb947a16a5aebf2b59fb8481866d28f96 (patch) | |
| tree | cdb566c89666f62b78bd3e432140aa86b23bf67a | |
| parent | 7667b84cc34707c28ca0db8d24f046ec34e8c25d (diff) | |
sqfs_dir_tree_destroy/sqfs_destroy: allow NULL input
Many library destructor functions (like free()) allow a NULL
pointer as input, and do nothing in that case.
This allows easier cleanup patterns: initialize pointers to NULL
and then always pass them to the destroyer functions, no need for
verbose goto/if-else patterns.
Signed-off-by: Luca Boccassi <luca.boccassi@microsoft.com>
| -rw-r--r-- | extras/extract_one.c | 39 | ||||
| -rw-r--r-- | include/sqfs/dir_reader.h | 2 | ||||
| -rw-r--r-- | include/sqfs/predef.h | 5 | ||||
| -rw-r--r-- | lib/sqfs/read_tree.c | 3 | 
4 files changed, 23 insertions, 26 deletions
diff --git a/extras/extract_one.c b/extras/extract_one.c index 4f5b547..fcd8124 100644 --- a/extras/extract_one.c +++ b/extras/extract_one.c @@ -52,7 +52,7 @@ int main(int argc, char **argv)  	ret = sqfs_super_read(&super, file);  	if (ret) {  		fprintf(stderr, "%s: error reading super block.\n", argv[1]); -		goto out_file; +		goto out;  	}  	sqfs_compressor_config_init(&cfg, super.compression_id, @@ -62,62 +62,62 @@ int main(int argc, char **argv)  	ret = sqfs_compressor_create(&cfg, &cmp);  	if (ret != 0) {  		fprintf(stderr, "%s: error creating compressor: %d.\n", argv[1], ret); -		goto out_file; +		goto out;  	}  	if (!(super.flags & SQFS_FLAG_NO_XATTRS)) {  		xattr = sqfs_xattr_reader_create(0);  		if (xattr == NULL) {  			fprintf(stderr, "%s: error creating xattr reader: %d.\n", argv[1], SQFS_ERROR_ALLOC); -			goto out_cmp; +			goto out;  		}  		ret = sqfs_xattr_reader_load(xattr, &super, file, cmp);  		if (ret) {  			fprintf(stderr, "%s: error loading xattr reader: %d.\n", argv[1], ret); -			goto out_xattr; +			goto out;  		}  	}  	idtbl = sqfs_id_table_create(0);  	if (idtbl == NULL) {  		fprintf(stderr, "%s: error creating ID table: %d.\n", argv[1], ret); -		goto out_xattr; +		goto out;  	}  	ret = sqfs_id_table_read(idtbl, file, &super, cmp);  	if (ret) {  		fprintf(stderr, "%s: error loading ID table: %d.\n", argv[1], ret); -		goto out_idtbl; +		goto out;  	}  	dirrd = sqfs_dir_reader_create(&super, cmp, file, 0);  	if (dirrd == NULL) {  		fprintf(stderr, "%s: error creating dir reader: %d.\n", argv[1], SQFS_ERROR_ALLOC); -		goto out_idtbl; +		goto out;  	}  	data = sqfs_data_reader_create(file, super.block_size, cmp, 0);  	if (data == NULL) {  		fprintf(stderr, "%s: error creating data reader: %d.\n", argv[1], SQFS_ERROR_ALLOC); -		goto out_dirrd; +		goto out;  	}  	ret = sqfs_data_reader_load_fragment_table(data, &super);  	if (ret) {  		fprintf(stderr, "%s: error loading fragment table: %d.\n", argv[1], ret); -		goto out_data; +		goto out;  	}  	ret = sqfs_dir_reader_get_full_hierarchy(dirrd, idtbl, argv[2], 0, &n);  	if (ret) {  		fprintf(stderr, "%s: error reading filesystem hierarchy: %d.\n", argv[1], ret); -		goto out_data; +		goto out;  	}  	if (!S_ISREG(n->inode->base.mode)) {  		fprintf(stderr, "/%s is not a file\n", argv[2]); -		goto out_tree; +		goto out;  	}  	sqfs_inode_get_file_size(n->inode, &file_size); @@ -125,7 +125,7 @@ int main(int argc, char **argv)  	output = p = malloc(file_size);  	if (output == NULL) {  		fprintf(stderr, "malloc failed: %d\n", errno); -		goto out_tree; +		goto out;  	}  	for (size_t i = 0; i < sqfs_inode_get_file_block_count(n->inode); ++i) { @@ -135,7 +135,7 @@ int main(int argc, char **argv)  		ret = sqfs_data_reader_get_block(data, n->inode, i, &chunk_size, &chunk);  		if (ret) {  			fprintf(stderr, "reading data block: %d\n", ret); -			goto out_tree; +			goto out;  		}  		memcpy(p, chunk, chunk_size); @@ -152,7 +152,7 @@ int main(int argc, char **argv)  		ret = sqfs_data_reader_get_fragment(data, n->inode, &chunk_size, &chunk);  		if (ret) {  			fprintf(stderr, "reading fragment block: %d\n", ret); -			goto out_tree; +			goto out;  		}  		memcpy(p, chunk, chunk_size); @@ -163,20 +163,13 @@ int main(int argc, char **argv)  	fprintf(stdout, "%s\n", (char *)output);  	status = EXIT_SUCCESS; -out_tree: +out:  	sqfs_dir_tree_destroy(n); -out_data:  	sqfs_destroy(data); -out_dirrd:  	sqfs_destroy(dirrd); -out_idtbl:  	sqfs_destroy(idtbl); -out_xattr: -	if (xattr != NULL) -		sqfs_destroy(xattr); -out_cmp: +	sqfs_destroy(xattr);  	sqfs_destroy(cmp); -out_file:  	sqfs_destroy(file);  	free(output); diff --git a/include/sqfs/dir_reader.h b/include/sqfs/dir_reader.h index 3bef7e3..2ee7204 100644 --- a/include/sqfs/dir_reader.h +++ b/include/sqfs/dir_reader.h @@ -320,7 +320,7 @@ SQFS_API int sqfs_dir_reader_get_full_hierarchy(sqfs_dir_reader_t *rd,   * This function can be used to clean up after   * @ref sqfs_dir_reader_get_full_hierarchy.   * - * @param root A pointer to the root node. + * @param root A pointer to the root node or NULL.   */  SQFS_API void sqfs_dir_tree_destroy(sqfs_tree_node_t *root); diff --git a/include/sqfs/predef.h b/include/sqfs/predef.h index 6296b4b..a976cd4 100644 --- a/include/sqfs/predef.h +++ b/include/sqfs/predef.h @@ -133,11 +133,12 @@ typedef struct sqfs_object_t {   *   * @memberof sqfs_object_t   * - * @param obj A pointer to an object + * @param obj A pointer to an object or NULL   */  static SQFS_INLINE void sqfs_destroy(void *obj)  { -	((sqfs_object_t *)obj)->destroy((sqfs_object_t *)obj); +	if (obj) +		((sqfs_object_t *)obj)->destroy((sqfs_object_t *)obj);  }  /** diff --git a/lib/sqfs/read_tree.c b/lib/sqfs/read_tree.c index 802446a..feda691 100644 --- a/lib/sqfs/read_tree.c +++ b/lib/sqfs/read_tree.c @@ -179,6 +179,9 @@ void sqfs_dir_tree_destroy(sqfs_tree_node_t *root)  {  	sqfs_tree_node_t *it; +	if (!root) +		return; +  	while (root->children != NULL) {  		it = root->children;  		root->children = it->next;  | 
