:: commit 662b5b76241f51d5dfdb99d86ba1e7c747173b45

mintsuki <mintsuki@protonmail.com> — 2021-06-12 06:03

parents: dc47b83c16

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];
tab: 248 wrap: offon