summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoman Artiukhin <bahusdrive@gmail.com>2024-11-24 16:31:59 +0200
committerRoman Artiukhin <bahusdrive@gmail.com>2024-12-11 11:36:08 +0200
commit18520c27a5bc03c7efffd91be802f7461dfe3711 (patch)
tree119d50b194956265986166b5e21e06e8e1c00e34
parentc1ee278abf66a40ec2698623f167dd5b9537a9b4 (diff)
downloadrockbox-18520c27a5.tar.gz
rockbox-18520c27a5.zip
metadata: mp3: Avoid utf-8 buffer stack allocation for utf-8 tags
Change-Id: I9f35fc017efa6e8f36cd295adf662612cf9c6c16
-rw-r--r--lib/rbcodec/metadata/id3tags.c64
1 files changed, 42 insertions, 22 deletions
diff --git a/lib/rbcodec/metadata/id3tags.c b/lib/rbcodec/metadata/id3tags.c
index 49316a34a9..70be23234f 100644
--- a/lib/rbcodec/metadata/id3tags.c
+++ b/lib/rbcodec/metadata/id3tags.c
@@ -539,10 +539,37 @@ static int unicode_len(char encoding, const void* string)
return len;
}
-/* Checks to see if the passed in string is a 16-bit wide Unicode v2
+/* Checks if passed string can be treated as utf-8 string and process it accordingly */
+static bool parse_as_utf8(char* string, int *len)
+{
+ switch (string[0])
+ {
+ case 0x01: /* Unicode with or without BOM */
+ case 0x02:
+ return false;
+
+ case 0x00: /* Type 0x00 is ordinary ISO 8859-1 */
+ if (get_codepage() != UTF_8)
+ return false;
+ // fallthrough
+ case 0x03: /* UTF-8 encoded string */
+ (*len)--;
+ memmove(string, string + 1, *len);
+ return true;
+
+ default: /* Plain old string */
+ if (get_codepage() == UTF_8)
+ {
+ return true;
+ }
+ return false;
+ }
+}
+
+/* Must be called after parse_as_utf8. Checks to see if the passed in string is a 16-bit wide Unicode v2
string. If it is, we convert it to a UTF-8 string. If it's not unicode,
we convert from the default codepage */
-static int unicode_munge(char* string, char* utf8buf, int *len) {
+static void unicode_munge(char* string, char* utf8buf, int *len) {
long tmp;
bool le = false;
int i = 0;
@@ -603,20 +630,13 @@ static int unicode_munge(char* string, char* utf8buf, int *len) {
} while(i < *len);
*len = templen - 1;
break;
-
- case 0x03: /* UTF-8 encoded string */
- for(i=0; i < *len; i++)
- utf8[i] = str[i+1];
- (*len)--;
- break;
-
+ /* case 0x03: UTF-8 encoded string handled by parse_as_utf8 */
default: /* Plain old string */
utf8 = iso_decode(str, utf8, -1, *len);
*utf8 = 0;
*len = (intptr_t)utf8 - (intptr_t)utf8buf;
break;
}
- return 0;
}
/*
@@ -783,7 +803,7 @@ void setid3v2title(int fd, struct mp3entry *entry)
int flags;
bool global_unsynch = false;
bool unsynch = false;
- int i, j;
+ int i;
int rc;
bool itunes_gapless = false;
@@ -1092,17 +1112,17 @@ retry_with_limit:
}
}
- /* UTF-8 could potentially be 3 times larger */
- /* so we need to create a new buffer */
- char utf8buf[(3 * bytesread) + 1];
-
- unicode_munge( tag, utf8buf, &bytesread );
-
- if(bytesread >= buffersize - bufferpos)
- bytesread = buffersize - bufferpos - 1;
-
- for (j = 0; j < bytesread; j++)
- tag[j] = utf8buf[j];
+ if (!parse_as_utf8(tag, &bytesread))
+ {
+ /* UTF-8 could potentially be 3 times larger */
+ /* so we need to create a new buffer */
+ char utf8buf[(3 * bytesread) + 1];
+ unicode_munge( tag, utf8buf, &bytesread);
+ if(bytesread >= buffersize - bufferpos)
+ bytesread = buffersize - bufferpos - 1;
+
+ memcpy(tag, utf8buf, bytesread);
+ }
/* remove trailing spaces */
while ( bytesread > 0 && isspace(tag[bytesread-1]))