diff --git a/fs/cromfs/fs_cromfs.c b/fs/cromfs/fs_cromfs.c index 13a837db431..11921807c5f 100644 --- a/fs/cromfs/fs_cromfs.c +++ b/fs/cromfs/fs_cromfs.c @@ -600,10 +600,20 @@ static ssize_t cromfs_read(FAR struct file *filep, FAR char *buffer, if (filep->f_pos > ff->ff_node->cn_size) { - /* Return the end-of-file indication */ + /* Start read position is past the end of file. Return the end-of- + * file indication. + */ return 0; } + else if ((filep->f_pos + buflen) > ff->ff_node->cn_size) + { + /* The final read position is past the end of file. Truncate the + * read length. + */ + + buflen = ff->ff_node->cn_size - filep->f_pos; + } /* Find the compressed block containing the current offset, f_pos */ @@ -633,7 +643,7 @@ static ssize_t cromfs_read(FAR struct file *filep, FAR char *buffer, /* Go to the next block */ currhdr = nexthdr; - blkoffs += blksize; + blkoffs += ulen; if (currhdr->lzf_type == LZF_TYPE0_HDR) { @@ -641,7 +651,7 @@ static ssize_t cromfs_read(FAR struct file *filep, FAR char *buffer, (FAR struct lzf_type0_header_s *)currhdr; ulen = (uint16_t)hdr0->lzf_len[0] << 8 | - (uint16_t)hdr0->lzf_len[0]; + (uint16_t)hdr0->lzf_len[1]; blksize = (size_t)ulen + LZF_TYPE0_HDR_SIZE; } else @@ -650,15 +660,15 @@ static ssize_t cromfs_read(FAR struct file *filep, FAR char *buffer, (FAR struct lzf_type1_header_s *)currhdr; ulen = (uint16_t)hdr1->lzf_ulen[0] << 8 | - (uint16_t)hdr1->lzf_ulen[0]; + (uint16_t)hdr1->lzf_ulen[1]; clen = (uint16_t)hdr1->lzf_clen[0] << 8 | - (uint16_t)hdr1->lzf_clen[0]; + (uint16_t)hdr1->lzf_clen[1]; blksize = (size_t)clen + LZF_TYPE1_HDR_SIZE; } - nexthdr = (FAR struct lzf_header_s *)((FAR uint8_t *)currhdr + blksize); + nexthdr = (FAR struct lzf_header_s *)((FAR uint8_t *)currhdr + blksize); } - while (blkoffs <= fpos && (blkoffs + ulen) > fpos); + while (blkoffs < fpos && (blkoffs + ulen) > fpos); /* Check if we need to decompress the next block into the user buffer */ @@ -695,9 +705,9 @@ static ssize_t cromfs_read(FAR struct file *filep, FAR char *buffer, copysize = remaining; } - src = (FAR const uint8_t *)currhdr + LZF_TYPE1_HDR_SIZE; + src = (FAR const uint8_t *)currhdr + LZF_TYPE1_HDR_SIZE; decomplen = lzf_decompress(src, clen, dest, copysize); - DEBUGASSERT(decomplen = copysize); + DEBUGASSERT(decomplen == copysize); } else { @@ -728,14 +738,14 @@ static ssize_t cromfs_read(FAR struct file *filep, FAR char *buffer, memcpy(dest, &ff->ff_buffer[copyoffs], copysize); } } + + /* Adjust pointers counts and offset */ + + dest += copysize; + remaining -= copysize; + fpos += copysize; } - /* Adjust pointers counts and offset */ - - dest += copysize; - remaining -= copysize; - fpos += copysize; - /* Update the file pointer */ filep->f_pos = fpos; @@ -1021,7 +1031,9 @@ static int cromfs_bind(FAR struct inode *blkdriver, const void *data, void **handle) { finfo("blkdriver: %p data: %p handle: %p\n", blkdriver, data, handle); + DEBUGASSERT(blkdriver == NULL && handle != NULL); + DEBUGASSERT(g_cromfs_image.cv_magic == CROMFS_MAGIC); /* Return the new file system handle */ diff --git a/tools/gencromfs.c b/tools/gencromfs.c index 062e5c034e4..8f3c378ab38 100644 --- a/tools/gencromfs.c +++ b/tools/gencromfs.c @@ -39,6 +39,7 @@ #define _GNU_SOURCE 1 #include +#include #include #include #include @@ -238,9 +239,12 @@ static size_t lzf_compress(const uint8_t *inbuffer, unsigned int inlen, union lzf_result_u *result); static mode_t get_mode(mode_t mode); static void gen_dirlink(const char *name, size_t tgtoffs); -static void gen_directory(const char *path, const char *name, mode_t mode); -static void gen_file(const char *path, const char *name, mode_t mode); -static void process_direntry(const char *dirpath, struct dirent *direntry); +static void gen_directory(const char *path, const char *name, mode_t mode, + bool lastentry); +static void gen_file(const char *path, const char *name, mode_t mode, + bool lastentry); +static void process_direntry(const char *dirpath, struct dirent *direntry, + bool lastentry); static void traverse_directory(const char *dirpath); /**************************************************************************** @@ -866,7 +870,8 @@ static void gen_dirlink(const char *name, size_t tgtoffs) g_nnodes++; } -static void gen_directory(const char *path, const char *name, mode_t mode) +static void gen_directory(const char *path, const char *name, mode_t mode, + bool lastentry) { struct cromfs_node_s node; size_t save_offset = g_offset; @@ -923,7 +928,7 @@ static void gen_directory(const char *path, const char *name, mode_t mode) node.cn_size = 0; save_offset += namlen; - node.cn_peer = g_offset; + node.cn_peer = lastentry ? 0 : g_offset; node.u.cn_child = save_offset; fprintf(g_tmpstream, "\n /* Offset %6lu: Directory %s */\n\n", @@ -939,7 +944,8 @@ static void gen_directory(const char *path, const char *name, mode_t mode) append_tmpfile(g_tmpstream, subtree_stream); } -static void gen_file(const char *path, const char *name, mode_t mode) +static void gen_file(const char *path, const char *name, mode_t mode, + bool lastentry) { struct cromfs_node_s node; union lzf_result_u result; @@ -1043,7 +1049,7 @@ static void gen_file(const char *path, const char *name, mode_t mode) node.u.cn_blocks = nodeoffs; nodeoffs += blktotal; - node.cn_peer = nodeoffs; + node.cn_peer = lastentry ? 0 : nodeoffs; dump_hexbuffer(g_tmpstream, &node, sizeof(struct cromfs_node_s)); dump_hexbuffer(g_tmpstream, name, namlen); @@ -1055,7 +1061,8 @@ static void gen_file(const char *path, const char *name, mode_t mode) append_tmpfile(g_tmpstream, outstream); } -static void process_direntry(const char *dirpath, struct dirent *direntry) +static void process_direntry(const char *dirpath, struct dirent *direntry, + bool lastentry) { struct stat buf; char *path; @@ -1084,11 +1091,11 @@ static void process_direntry(const char *dirpath, struct dirent *direntry) else if (S_ISDIR(buf.st_mode)) { - gen_directory(path, direntry->d_name, buf.st_mode); + gen_directory(path, direntry->d_name, buf.st_mode, lastentry); } else if (S_ISREG(buf.st_mode)) { - gen_file(path, direntry->d_name, buf.st_mode); + gen_file(path, direntry->d_name, buf.st_mode, lastentry); } else { @@ -1102,6 +1109,7 @@ static void traverse_directory(const char *dirpath) { DIR *dirp; struct dirent *direntry; + struct dirent *nextentry; /* Open the directory */ @@ -1115,23 +1123,29 @@ static void traverse_directory(const char *dirpath) /* Visit each entry in the directory */ - do + direntry = readdir(dirp); + while (direntry != NULL) { - direntry = readdir(dirp); - if (direntry != NULL) + /* Get the next entry so that we can anticipate the end of the + * directory. + */ + + nextentry = readdir(dirp); + + /* Skip the '.' and '..' hard links */ + + if (strcmp(direntry->d_name, ".") != 0 && + strcmp(direntry->d_name, "..") != 0) { - /* Skip the '.' and '..' hard links */ + /* Process the directory entry */ - if (strcmp(direntry->d_name, ".") != 0 && - strcmp(direntry->d_name, "..") != 0) - { - /* Process the directory entry */ - - process_direntry(dirpath, direntry); - } + process_direntry(dirpath, direntry, nextentry == NULL); } + + /* Skip to the next entry */ + + direntry = nextentry; } - while (direntry != NULL); } /****************************************************************************