Fixed various memory leaks
This commit is contained in:
parent
914d3caaed
commit
8d2aeab016
10 changed files with 127 additions and 51 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -7,3 +7,4 @@
|
||||||
*.o
|
*.o
|
||||||
.settings/language.settings.xml
|
.settings/language.settings.xml
|
||||||
test/test_ipfs
|
test/test_ipfs
|
||||||
|
main/ipfs
|
||||||
|
|
|
@ -277,3 +277,33 @@ int ipfs_blockstore_put_node(const struct Node* node, const struct FSRepo* fs_re
|
||||||
free(filename);
|
free(filename);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***
|
||||||
|
* Find a UnixFS struct based on its hash
|
||||||
|
* @param hash the hash to look for
|
||||||
|
* @param hash_length the length of the hash
|
||||||
|
* @param unix_fs the struct to fill
|
||||||
|
* @param fs_repo where to look for the data
|
||||||
|
* @returns true(1) on success
|
||||||
|
*/
|
||||||
|
int ipfs_blockstore_get_node(const unsigned char* hash, size_t hash_length, struct Node** node, const struct FSRepo* fs_repo) {
|
||||||
|
// get datastore key, which is a base32 key of the multihash
|
||||||
|
unsigned char* key = ipfs_blockstore_hash_to_base32(hash, hash_length);
|
||||||
|
|
||||||
|
char* filename = ipfs_blockstore_path_get(fs_repo, (char*)key);
|
||||||
|
|
||||||
|
size_t file_size = os_utils_file_size(filename);
|
||||||
|
unsigned char buffer[file_size];
|
||||||
|
|
||||||
|
FILE* file = fopen(filename, "rb");
|
||||||
|
size_t bytes_read = fread(buffer, 1, file_size, file);
|
||||||
|
fclose(file);
|
||||||
|
|
||||||
|
int retVal = ipfs_node_protobuf_decode(buffer, bytes_read, node);
|
||||||
|
|
||||||
|
free(key);
|
||||||
|
free(filename);
|
||||||
|
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,31 +23,59 @@ size_t ipfs_import_chunk(FILE* file, struct Node* parent_node, struct FSRepo* fs
|
||||||
unsigned char buffer[MAX_DATA_SIZE];
|
unsigned char buffer[MAX_DATA_SIZE];
|
||||||
size_t bytes_read = fread(buffer, 1, MAX_DATA_SIZE, file);
|
size_t bytes_read = fread(buffer, 1, MAX_DATA_SIZE, file);
|
||||||
|
|
||||||
// put the file bits into a new UnixFS file
|
// structs used by this method
|
||||||
struct UnixFS* new_unixfs = NULL;
|
struct UnixFS* new_unixfs = NULL;
|
||||||
ipfs_unixfs_new(&new_unixfs);
|
struct Node* new_node = NULL;
|
||||||
|
struct NodeLink* new_link = NULL;
|
||||||
|
|
||||||
|
// put the file bits into a new UnixFS file
|
||||||
|
if (ipfs_unixfs_new(&new_unixfs) == 0)
|
||||||
|
return 0;
|
||||||
new_unixfs->data_type = UNIXFS_FILE;
|
new_unixfs->data_type = UNIXFS_FILE;
|
||||||
ipfs_unixfs_add_data(&buffer[0], bytes_read, new_unixfs);
|
if (ipfs_unixfs_add_data(&buffer[0], bytes_read, new_unixfs) == 0) {
|
||||||
|
ipfs_unixfs_free(new_unixfs);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
// protobuf the UnixFS
|
// protobuf the UnixFS
|
||||||
size_t protobuf_size = ipfs_unixfs_protobuf_encode_size(new_unixfs);
|
size_t protobuf_size = ipfs_unixfs_protobuf_encode_size(new_unixfs);
|
||||||
|
if (protobuf_size == 0) {
|
||||||
|
ipfs_unixfs_free(new_unixfs);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
unsigned char protobuf[protobuf_size];
|
unsigned char protobuf[protobuf_size];
|
||||||
size_t bytes_written = 0;
|
size_t bytes_written = 0;
|
||||||
ipfs_unixfs_protobuf_encode(new_unixfs, protobuf, protobuf_size, &bytes_written);
|
if (ipfs_unixfs_protobuf_encode(new_unixfs, protobuf, protobuf_size, &bytes_written) == 0) {
|
||||||
// we're done with the object
|
ipfs_unixfs_free(new_unixfs);
|
||||||
ipfs_unixfs_free(new_unixfs);
|
return 0;
|
||||||
|
}
|
||||||
// create a new node
|
// create a new node
|
||||||
struct Node* new_node = NULL;
|
if (ipfs_node_new_from_data(protobuf, bytes_written, &new_node) == 0) {
|
||||||
ipfs_node_new_from_data(protobuf, bytes_written, &new_node);
|
return 0;
|
||||||
ipfs_node_set_hash(new_node, new_unixfs->hash, new_unixfs->hash_length);
|
}
|
||||||
|
if (ipfs_node_set_hash(new_node, new_unixfs->hash, new_unixfs->hash_length) == 0) {
|
||||||
|
ipfs_node_free(new_node);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
// we're done with the UnixFS object
|
||||||
|
ipfs_unixfs_free(new_unixfs);
|
||||||
// persist
|
// persist
|
||||||
size_t size_of_node = 0;
|
size_t size_of_node = 0;
|
||||||
ipfs_merkledag_add(new_node, fs_repo, &size_of_node);
|
if (ipfs_merkledag_add(new_node, fs_repo, &size_of_node) == 0) {
|
||||||
|
ipfs_node_free(new_node);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
// put link in parent node
|
// put link in parent node
|
||||||
struct NodeLink* new_link = NULL;
|
if (ipfs_node_link_create("", new_node->hash, new_node->hash_size, &new_link) == 0) {
|
||||||
ipfs_node_link_create("", new_node->hash, new_node->hash_size, &new_link);
|
ipfs_node_free(new_node);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
new_link->t_size = size_of_node;
|
new_link->t_size = size_of_node;
|
||||||
*total_size += new_link->t_size;
|
*total_size += new_link->t_size;
|
||||||
ipfs_node_add_link(parent_node, new_link);
|
// NOTE: disposal of this link object happens when the parent is disposed
|
||||||
|
if (ipfs_node_add_link(parent_node, new_link) == 0) {
|
||||||
|
ipfs_node_free(new_node);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
ipfs_node_free(new_node);
|
ipfs_node_free(new_node);
|
||||||
if (bytes_read != MAX_DATA_SIZE) {
|
if (bytes_read != MAX_DATA_SIZE) {
|
||||||
// We have read everything, now save the parent_node,
|
// We have read everything, now save the parent_node,
|
||||||
|
@ -138,6 +166,8 @@ int ipfs_import(int argc, char** argv) {
|
||||||
retVal = ipfs_cid_hash_to_base58(directory_node->hash, directory_node->hash_size, buffer, buffer_len);
|
retVal = ipfs_cid_hash_to_base58(directory_node->hash, directory_node->hash_size, buffer, buffer_len);
|
||||||
if (retVal == 0) {
|
if (retVal == 0) {
|
||||||
printf("Unable to generate hash\n");
|
printf("Unable to generate hash\n");
|
||||||
|
ipfs_node_free(directory_node);
|
||||||
|
ipfs_repo_fsrepo_free(fs_repo);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
printf("added %s %s\n", buffer, argv[2]);
|
printf("added %s %s\n", buffer, argv[2]);
|
||||||
|
|
|
@ -60,5 +60,6 @@ int ipfs_blockstore_get_unixfs(const unsigned char* hash, size_t hash_length, st
|
||||||
* Put a struct Node in the blockstore
|
* Put a struct Node in the blockstore
|
||||||
*/
|
*/
|
||||||
int ipfs_blockstore_put_node(const struct Node* node, const struct FSRepo* fs_repo, size_t* bytes_written);
|
int ipfs_blockstore_put_node(const struct Node* node, const struct FSRepo* fs_repo, size_t* bytes_written);
|
||||||
|
int ipfs_blockstore_get_node(const unsigned char* hash, size_t hash_length, struct Node** node, const struct FSRepo* fs_repo);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -20,20 +20,22 @@ int ipfs_merkledag_add(struct Node* node, struct FSRepo* fs_repo, size_t* bytes_
|
||||||
// taken from merkledag.go line 59
|
// taken from merkledag.go line 59
|
||||||
int retVal = 0;
|
int retVal = 0;
|
||||||
|
|
||||||
// compute the hash
|
// compute the hash if necessary
|
||||||
size_t protobuf_size = ipfs_node_protobuf_encode_size(node);
|
|
||||||
unsigned char protobuf[protobuf_size];
|
|
||||||
size_t bytes_encoded;
|
|
||||||
retVal = ipfs_node_protobuf_encode(node, protobuf, protobuf_size, &bytes_encoded);
|
|
||||||
|
|
||||||
node->hash_size = 32;
|
|
||||||
node->hash = (unsigned char*)malloc(node->hash_size);
|
|
||||||
if (node->hash == NULL) {
|
if (node->hash == NULL) {
|
||||||
return 0;
|
size_t protobuf_size = ipfs_node_protobuf_encode_size(node);
|
||||||
}
|
unsigned char protobuf[protobuf_size];
|
||||||
if (libp2p_crypto_hashing_sha256(protobuf, bytes_encoded, &node->hash[0]) == 0) {
|
size_t bytes_encoded;
|
||||||
free(node->hash);
|
retVal = ipfs_node_protobuf_encode(node, protobuf, protobuf_size, &bytes_encoded);
|
||||||
return 0;
|
|
||||||
|
node->hash_size = 32;
|
||||||
|
node->hash = (unsigned char*)malloc(node->hash_size);
|
||||||
|
if (node->hash == NULL) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (libp2p_crypto_hashing_sha256(protobuf, bytes_encoded, &node->hash[0]) == 0) {
|
||||||
|
free(node->hash);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// write to block store & datastore
|
// write to block store & datastore
|
||||||
|
@ -56,8 +58,6 @@ int ipfs_merkledag_add(struct Node* node, struct FSRepo* fs_repo, size_t* bytes_
|
||||||
*/
|
*/
|
||||||
int ipfs_merkledag_get(const unsigned char* hash, size_t hash_size, struct Node** node, const struct FSRepo* fs_repo) {
|
int ipfs_merkledag_get(const unsigned char* hash, size_t hash_size, struct Node** node, const struct FSRepo* fs_repo) {
|
||||||
int retVal = 1;
|
int retVal = 1;
|
||||||
//struct Block* block;
|
|
||||||
struct UnixFS* unix_fs;
|
|
||||||
size_t key_length = 100;
|
size_t key_length = 100;
|
||||||
unsigned char key[key_length];
|
unsigned char key[key_length];
|
||||||
|
|
||||||
|
@ -67,27 +67,11 @@ int ipfs_merkledag_get(const unsigned char* hash, size_t hash_size, struct Node*
|
||||||
if (retVal == 0)
|
if (retVal == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// we have the record from the db. Go get the UnixFS from the blockstore
|
// we have the record from the db. Go get the node from the blockstore
|
||||||
retVal = ipfs_repo_fsrepo_unixfs_read(hash, hash_size, &unix_fs, fs_repo);
|
retVal = ipfs_repo_fsrepo_node_read(hash, hash_size, node, fs_repo);
|
||||||
if (retVal == 0) {
|
if (retVal == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// now convert the block into a node
|
|
||||||
if (ipfs_node_protobuf_decode(unix_fs->bytes, unix_fs->bytes_size, node) == 0) {
|
|
||||||
ipfs_unixfs_free(unix_fs);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// set the cid on the node
|
|
||||||
if (ipfs_node_set_hash(*node, hash, hash_size) == 0) {
|
|
||||||
ipfs_unixfs_free(unix_fs);
|
|
||||||
ipfs_node_free(*node);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// free resources
|
|
||||||
ipfs_unixfs_free(unix_fs);
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -375,9 +375,6 @@ int ipfs_node_set_data(struct Node * N, unsigned char * Data, size_t data_size)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
N->encoded = NULL;
|
|
||||||
N->hash = NULL;
|
|
||||||
N->hash_size = 0;
|
|
||||||
N->data = malloc(sizeof(unsigned char) * data_size);
|
N->data = malloc(sizeof(unsigned char) * data_size);
|
||||||
if (N->data == NULL)
|
if (N->data == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -613,7 +613,18 @@ int ipfs_repo_fsrepo_node_write(const struct Node* node, const struct FSRepo* fs
|
||||||
}
|
}
|
||||||
|
|
||||||
int ipfs_repo_fsrepo_node_read(const unsigned char* hash, size_t hash_length, struct Node** node, const struct FSRepo* fs_repo) {
|
int ipfs_repo_fsrepo_node_read(const unsigned char* hash, size_t hash_length, struct Node** node, const struct FSRepo* fs_repo) {
|
||||||
return 0;
|
int retVal = 0;
|
||||||
|
|
||||||
|
// get the base32 hash from the database
|
||||||
|
// We do this only to see if it is in the database
|
||||||
|
size_t fs_key_length = 100;
|
||||||
|
unsigned char fs_key[fs_key_length];
|
||||||
|
retVal = fs_repo->config->datastore->datastore_get((const char*)hash, hash_length, fs_key, fs_key_length, &fs_key_length, fs_repo->config->datastore);
|
||||||
|
if (retVal == 0) // maybe it doesn't exist?
|
||||||
|
return 0;
|
||||||
|
// now get the block from the blockstore
|
||||||
|
retVal = ipfs_blockstore_get_node(hash, hash_length, node, fs_repo);
|
||||||
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -64,6 +64,7 @@ int test_import_large_file() {
|
||||||
if (write_node->hash[i] != cid_test[i]) {
|
if (write_node->hash[i] != cid_test[i]) {
|
||||||
printf("Hashes should be the same each time, and do not match at position %d, should be %02x but is %02x\n", i, cid_test[i], write_node->hash[i]);
|
printf("Hashes should be the same each time, and do not match at position %d, should be %02x but is %02x\n", i, cid_test[i], write_node->hash[i]);
|
||||||
ipfs_repo_fsrepo_free(fs_repo);
|
ipfs_repo_fsrepo_free(fs_repo);
|
||||||
|
ipfs_node_free(write_node);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -210,6 +211,7 @@ int test_import_small_file() {
|
||||||
if (write_node->hash[i] != cid_test[i]) {
|
if (write_node->hash[i] != cid_test[i]) {
|
||||||
printf("Hashes do not match at position %d, should be %02x but is %02x\n", i, cid_test[i], write_node->hash[i]);
|
printf("Hashes do not match at position %d, should be %02x but is %02x\n", i, cid_test[i], write_node->hash[i]);
|
||||||
ipfs_repo_fsrepo_free(fs_repo);
|
ipfs_repo_fsrepo_free(fs_repo);
|
||||||
|
ipfs_node_free(write_node);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@ int test_unixfs_encode_decode() {
|
||||||
|
|
||||||
retVal = ipfs_unixfs_protobuf_encode(unixfs, buffer, buffer_size, &bytes_written);
|
retVal = ipfs_unixfs_protobuf_encode(unixfs, buffer, buffer_size, &bytes_written);
|
||||||
if (retVal == 0) {
|
if (retVal == 0) {
|
||||||
|
ipfs_unixfs_free(unixfs);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,18 +23,25 @@ int test_unixfs_encode_decode() {
|
||||||
struct UnixFS* results = NULL;
|
struct UnixFS* results = NULL;
|
||||||
retVal = ipfs_unixfs_protobuf_decode(buffer, bytes_written, &results);
|
retVal = ipfs_unixfs_protobuf_decode(buffer, bytes_written, &results);
|
||||||
if (retVal == 0) {
|
if (retVal == 0) {
|
||||||
|
ipfs_unixfs_free(unixfs);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// compare
|
// compare
|
||||||
if (results->data_type != unixfs->data_type) {
|
if (results->data_type != unixfs->data_type) {
|
||||||
|
ipfs_unixfs_free(unixfs);
|
||||||
|
ipfs_unixfs_free(results);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (results->block_size_head != unixfs->block_size_head) {
|
if (results->block_size_head != unixfs->block_size_head) {
|
||||||
|
ipfs_unixfs_free(unixfs);
|
||||||
|
ipfs_unixfs_free(results);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ipfs_unixfs_free(unixfs);
|
||||||
|
ipfs_unixfs_free(results);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,15 +79,21 @@ int test_unixfs_encode_smallfile() {
|
||||||
size_t bytes_written;
|
size_t bytes_written;
|
||||||
ipfs_unixfs_protobuf_encode(unixfs, protobuf, protobuf_size, &bytes_written);
|
ipfs_unixfs_protobuf_encode(unixfs, protobuf, protobuf_size, &bytes_written);
|
||||||
|
|
||||||
|
int retVal = 1;
|
||||||
|
|
||||||
if (bytes_written != 41) {
|
if (bytes_written != 41) {
|
||||||
printf("Length should be %lu, but is %lu\n", 41LU, bytes_written);
|
printf("Length should be %lu, but is %lu\n", 41LU, bytes_written);
|
||||||
|
retVal = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(int i = 0; i < bytes_written; i++) {
|
for(int i = 0; i < bytes_written; i++) {
|
||||||
if (expected_results[i] != protobuf[i]) {
|
if (expected_results[i] != protobuf[i]) {
|
||||||
printf("Byte at position %d should be %02x but is %02x\n", i, expected_results[i], protobuf[i]);
|
printf("Byte at position %d should be %02x but is %02x\n", i, expected_results[i], protobuf[i]);
|
||||||
|
retVal = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
ipfs_unixfs_free(unixfs);
|
||||||
|
|
||||||
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,6 +53,12 @@ int ipfs_unixfs_new(struct UnixFS** obj) {
|
||||||
|
|
||||||
int ipfs_unixfs_free(struct UnixFS* obj) {
|
int ipfs_unixfs_free(struct UnixFS* obj) {
|
||||||
if (obj != NULL) {
|
if (obj != NULL) {
|
||||||
|
if (obj->hash != NULL) {
|
||||||
|
free(obj->hash);
|
||||||
|
}
|
||||||
|
if (obj->bytes != NULL) {
|
||||||
|
free(obj->bytes);
|
||||||
|
}
|
||||||
free(obj);
|
free(obj);
|
||||||
obj = NULL;
|
obj = NULL;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue