All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/1] fs: fat: structure for name and extension
@ 2021-01-20 23:55 Heinrich Schuchardt
  0 siblings, 0 replies; only message in thread
From: Heinrich Schuchardt @ 2021-01-20 23:55 UTC (permalink / raw)
  To: u-boot

The short name and extension of FAT files are stored in adjacent fields of
the directory entry. For some operations like calculating a checksum or
copying both fields it is preferable to treat both as one structure.

Change the definition of the directory entry structure to include a
structure comprising the name and the extension field.

This resolves Coverity CID 316357, CID 316350, CID 316348.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
---
 fs/fat/fat.c       | 32 ++++++++++++++++----------------
 fs/fat/fat_write.c | 20 +++++++++-----------
 include/fat.h      |  7 ++++++-
 3 files changed, 31 insertions(+), 28 deletions(-)

diff --git a/fs/fat/fat.c b/fs/fat/fat.c
index 157dad60a4..fb6ce094ac 100644
--- a/fs/fat/fat.c
+++ b/fs/fat/fat.c
@@ -123,16 +123,16 @@ static void get_name(dir_entry *dirent, char *s_name)
 {
 	char *ptr;

-	memcpy(s_name, dirent->name, 8);
+	memcpy(s_name, dirent->nameext.name, 8);
 	s_name[8] = '\0';
 	ptr = s_name;
 	while (*ptr && *ptr != ' ')
 		ptr++;
 	if (dirent->lcase & CASE_LOWER_BASE)
 		downcase(s_name, (unsigned)(ptr - s_name));
-	if (dirent->ext[0] && dirent->ext[0] != ' ') {
+	if (dirent->nameext.ext[0] && dirent->nameext.ext[0] != ' ') {
 		*ptr++ = '.';
-		memcpy(ptr, dirent->ext, 3);
+		memcpy(ptr, dirent->nameext.ext, 3);
 		if (dirent->lcase & CASE_LOWER_EXT)
 			downcase(ptr, 3);
 		ptr[3] = '\0';
@@ -472,16 +472,15 @@ static int slot2str(dir_slot *slotptr, char *l_name, int *idx)
 }

 /* Calculate short name checksum */
-static __u8 mkcksum(const char name[8], const char ext[3])
+static __u8 mkcksum(struct nameext *nameext)
 {
 	int i;
+	u8 *pos = (void *)nameext;

 	__u8 ret = 0;

-	for (i = 0; i < 8; i++)
-		ret = (((ret & 1) << 7) | ((ret & 0xfe) >> 1)) + name[i];
-	for (i = 0; i < 3; i++)
-		ret = (((ret & 1) << 7) | ((ret & 0xfe) >> 1)) + ext[i];
+	for (i = 0; i < 11; i++)
+		ret = (((ret & 1) << 7) | ((ret & 0xfe) >> 1)) + pos[i];

 	return ret;
 }
@@ -896,7 +895,7 @@ static dir_entry *next_dent(fat_itr *itr)
 	}

 	/* have we reached the last valid entry? */
-	if (itr->dent->name[0] == 0)
+	if (itr->dent->nameext.name[0] == 0)
 		return NULL;

 	return itr->dent;
@@ -905,7 +904,7 @@ static dir_entry *next_dent(fat_itr *itr)
 static dir_entry *extract_vfat_name(fat_itr *itr)
 {
 	struct dir_entry *dent = itr->dent;
-	int seqn = itr->dent->name[0] & ~LAST_LONG_ENTRY_MASK;
+	int seqn = itr->dent->nameext.name[0] & ~LAST_LONG_ENTRY_MASK;
 	u8 chksum, alias_checksum = ((dir_slot *)dent)->alias_checksum;
 	int n = 0;

@@ -932,18 +931,19 @@ static dir_entry *extract_vfat_name(fat_itr *itr)
 	 * We are now at the short file name entry.
 	 * If it is marked as deleted, just skip it.
 	 */
-	if (dent->name[0] == DELETED_FLAG ||
-	    dent->name[0] == aRING)
+	if (dent->nameext.name[0] == DELETED_FLAG ||
+	    dent->nameext.name[0] == aRING)
 		return NULL;

 	itr->l_name[n] = '\0';

-	chksum = mkcksum(dent->name, dent->ext);
+	chksum = mkcksum(&dent->nameext);

 	/* checksum mismatch could mean deleted file, etc.. skip it: */
 	if (chksum != alias_checksum) {
 		debug("** chksum=%x, alias_checksum=%x, l_name=%s, s_name=%8s.%3s\n",
-		      chksum, alias_checksum, itr->l_name, dent->name, dent->ext);
+		      chksum, alias_checksum, itr->l_name, dent->nameext.name,
+		      dent->nameext.ext);
 		return NULL;
 	}

@@ -984,12 +984,12 @@ static int fat_itr_next(fat_itr *itr)
 		itr->dent_rem = itr->remaining;
 		itr->dent_start = itr->dent;
 		itr->dent_clust = itr->clust;
-		if (dent->name[0] == DELETED_FLAG)
+		if (dent->nameext.name[0] == DELETED_FLAG)
 			continue;

 		if (dent->attr & ATTR_VOLUME) {
 			if ((dent->attr & ATTR_VFAT) == ATTR_VFAT &&
-			    (dent->name[0] & LAST_LONG_ENTRY_MASK)) {
+			    (dent->nameext.name[0] & LAST_LONG_ENTRY_MASK)) {
 				/* long file name */
 				dent = extract_vfat_name(itr);
 				/*
diff --git a/fs/fat/fat_write.c b/fs/fat/fat_write.c
index 2f4391e86f..a17e51750c 100644
--- a/fs/fat/fat_write.c
+++ b/fs/fat/fat_write.c
@@ -275,7 +275,7 @@ static int fat_find_empty_dentries(fat_itr *itr, int count)
 			log_debug("Not enough directory entries available\n");
 			return -ENOSPC;
 		}
-		switch (itr->dent->name[0]) {
+		switch (itr->dent->nameext.name[0]) {
 		case 0x00:
 		case DELETED_FLAG:
 			if (!n) {
@@ -399,7 +399,7 @@ fill_dir_slot(fat_itr *itr, const char *l_name, const char *shortname)
 	int idx = 0, ret;

 	/* Get short file name checksum value */
-	checksum = mkcksum(shortname, shortname + 8);
+	checksum = mkcksum((void *)shortname);

 	do {
 		memset(slotptr, 0x00, sizeof(dir_slot));
@@ -1169,7 +1169,7 @@ static void fill_dentry(fsdata *mydata, dir_entry *dentptr,

 	dentptr->attr = attr;

-	memcpy(dentptr->name, shortname, SHORT_NAME_SIZE);
+	memcpy(&dentptr->nameext, shortname, SHORT_NAME_SIZE);
 }

 /**
@@ -1194,7 +1194,7 @@ static dir_entry *find_directory_entry(fat_itr *itr, char *filename)
 		if (!match)
 			continue;

-		if (itr->dent->name[0] == '\0')
+		if (itr->dent->nameext.name[0] == '\0')
 			return NULL;
 		else
 			return itr->dent;
@@ -1470,7 +1470,7 @@ static int delete_single_dentry(fat_itr *itr)
 	struct dir_entry *dent = itr->dent;

 	memset(dent, 0, sizeof(*dent));
-	dent->name[0] = DELETED_FLAG;
+	dent->nameext.name[0] = DELETED_FLAG;

 	if (!itr->remaining)
 		return flush_dir(itr);
@@ -1486,7 +1486,7 @@ static int delete_single_dentry(fat_itr *itr)
 static int delete_long_name(fat_itr *itr)
 {
 	struct dir_entry *dent = itr->dent;
-	int seqn = itr->dent->name[0] & ~LAST_LONG_ENTRY_MASK;
+	int seqn = itr->dent->nameext.name[0] & ~LAST_LONG_ENTRY_MASK;

 	while (seqn--) {
 		int ret;
@@ -1531,7 +1531,7 @@ static int delete_dentry_long(fat_itr *itr)
 	dent = itr->dent_start;
 	/* Delete long name */
 	if ((dent->attr & ATTR_VFAT) == ATTR_VFAT &&
-	    (dent->name[0] & LAST_LONG_ENTRY_MASK)) {
+	    (dent->nameext.name[0] & LAST_LONG_ENTRY_MASK)) {
 		int ret;

 		ret = delete_long_name(itr);
@@ -1712,12 +1712,10 @@ int fat_mkdir(const char *new_dirname)
 	}
 	memset(dotdent, 0, bytesperclust);

-	memcpy(dotdent[0].name, ".       ", 8);
-	memcpy(dotdent[0].ext, "   ", 3);
+	memcpy(&dotdent[0].nameext, ".          ", 11);
 	dotdent[0].attr = ATTR_DIR | ATTR_ARCH;

-	memcpy(dotdent[1].name, "..      ", 8);
-	memcpy(dotdent[1].ext, "   ", 3);
+	memcpy(&dotdent[1].nameext, "..         ", 11);
 	dotdent[1].attr = ATTR_DIR | ATTR_ARCH;

 	if (itr->is_root)
diff --git a/include/fat.h b/include/fat.h
index b9f273f381..bd8e450b33 100644
--- a/include/fat.h
+++ b/include/fat.h
@@ -132,8 +132,13 @@ typedef struct volume_info
 #define CASE_LOWER_BASE	8	/* base (name) is lower case */
 #define CASE_LOWER_EXT	16	/* extension is lower case */

+struct nameext {
+	char name[8];
+	char ext[3];
+};
+
 typedef struct dir_entry {
-	char	name[8],ext[3];	/* Name and extension */
+	struct nameext nameext;	/* Name and extension */
 	__u8	attr;		/* Attribute bits */
 	__u8	lcase;		/* Case for name and ext (CASE_LOWER_x) */
 	__u8	ctime_ms;	/* Creation time, milliseconds */
--
2.29.2

^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2021-01-20 23:55 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-01-20 23:55 [PATCH 1/1] fs: fat: structure for name and extension Heinrich Schuchardt

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.