iso9660: Fix improper handling of filename casing
diff --git a/stage23/fs/iso9660.s2.c b/stage23/fs/iso9660.s2.c
index aa35ec8a..6d09d569 100644
--- a/stage23/fs/iso9660.s2.c
+++ b/stage23/fs/iso9660.s2.c
@@ -124,7 +124,7 @@ static struct iso9660_context *iso9660_get_context(struct volume *vol) {
return &node->context;
}
-static void load_name(char *buf, struct iso9660_directory_entry *entry) {
+static bool load_name(char *buf, struct iso9660_directory_entry *entry) {
unsigned char* sysarea = ((unsigned char*)entry) + sizeof(struct iso9660_directory_entry) + entry->filename_size;
int sysarea_len = entry->length - sizeof(struct iso9660_directory_entry) - entry->filename_size;
if ((entry->filename_size & 0x1) == 0) {
@@ -148,6 +148,7 @@ static void load_name(char *buf, struct iso9660_directory_entry *entry) {
name_len = rrnamelen;
memcpy(buf, sysarea + 5, name_len);
buf[name_len] = 0;
+ return true;
} else {
name_len = entry->filename_size;
size_t j;
@@ -156,23 +157,15 @@ static void load_name(char *buf, struct iso9660_directory_entry *entry) {
break;
if (entry->name[j] == '.' && entry->name[j+1] == ';')
break;
- buf[j] = tolower(entry->name[j]);
}
buf[j] = 0;
+ return false;
}
}
-static struct iso9660_directory_entry *iso9660_find(void *buffer, uint32_t size, const char *_filename) {
- char filename[strlen(_filename) + 1];
- size_t i = 0;
- while (*_filename)
- filename[i++] = tolower(*_filename++);
- filename[i] = 0;
-
+static struct iso9660_directory_entry *iso9660_find(void *buffer, uint32_t size, const char *filename) {
while (size) {
struct iso9660_directory_entry *entry = buffer;
- char entry_filename[128];
- load_name(entry_filename, entry);
if (entry->length == 0) {
if (size <= ISO9660_SECTOR_SIZE)
@@ -183,8 +176,17 @@ static struct iso9660_directory_entry *iso9660_find(void *buffer, uint32_t size,
continue;
}
- if (strcmp(filename, entry_filename) == 0) {
- return buffer;
+ char entry_filename[128];
+ bool rr = load_name(entry_filename, entry);
+
+ if (rr) {
+ if (strcmp(filename, entry_filename) == 0) {
+ return buffer;
+ }
+ } else {
+ if (strcasecmp(filename, entry_filename) == 0) {
+ return buffer;
+ }
}
size -= entry->length;
diff --git a/stage23/lib/libc.h b/stage23/lib/libc.h
index 43bdd5ae..7f7d91bb 100644
--- a/stage23/lib/libc.h
+++ b/stage23/lib/libc.h
@@ -15,6 +15,7 @@ char *strcpy(char *, const char *);
char *strncpy(char *, const char *, size_t);
size_t strlen(const char *);
int strcmp(const char *, const char *);
+int strcasecmp(const char *, const char *);
int strncmp(const char *, const char *, size_t);
int inet_pton(const char *src, void *dst);
diff --git a/stage23/lib/libc.s2.c b/stage23/lib/libc.s2.c
index f8289973..aa3112e7 100644
--- a/stage23/lib/libc.s2.c
+++ b/stage23/lib/libc.s2.c
@@ -100,6 +100,16 @@ int strcmp(const char *s1, const char *s2) {
}
}
+int strcasecmp(const char *s1, const char *s2) {
+ for (size_t i = 0; ; i++) {
+ char c1 = s1[i], c2 = s2[i];
+ if (tolower(c1) != tolower(c2))
+ return c1 < c2 ? -1 : 1;
+ if (!c1)
+ return 0;
+ }
+}
+
int strncmp(const char *s1, const char *s2, size_t n) {
for (size_t i = 0; i < n; i++) {
char c1 = s1[i], c2 = s2[i];
