mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-10-13 18:17:39 -04:00
unicode: add iso_decode_ex with utf8 buffer size check
Make use of it in id3tags, playlist and cuesheet Change-Id: Ibc8abc0faf16688bc9b826b7a712d1dfe9bf75b2
This commit is contained in:
parent
f8fa1e7d5a
commit
004304dc65
5 changed files with 56 additions and 37 deletions
|
@ -245,8 +245,8 @@ static int alloc_and_load_cp_table(int cp, void *buf)
|
|||
return -1;
|
||||
}
|
||||
|
||||
/* Encode a UCS value as UTF-8 and return a pointer after this UTF-8 char. */
|
||||
unsigned char* utf8encode(unsigned long ucs, unsigned char *utf8)
|
||||
/* returns number of additional bytes required in encoded string (bytes_count - 1) */
|
||||
static int utf8_ucs_get_extra_bytes_count(unsigned long ucs)
|
||||
{
|
||||
int tail = 0;
|
||||
|
||||
|
@ -254,17 +254,41 @@ unsigned char* utf8encode(unsigned long ucs, unsigned char *utf8)
|
|||
while (ucs >> (5*tail + 6))
|
||||
tail++;
|
||||
|
||||
return tail;
|
||||
}
|
||||
|
||||
static unsigned char * utf8encode_internal(unsigned long ucs, unsigned char *utf8, int tail)
|
||||
{
|
||||
*utf8++ = (ucs >> (6*tail)) | utf8comp[tail];
|
||||
while (tail--)
|
||||
*utf8++ = ((ucs >> (6*tail)) & (MASK ^ 0xFF)) | COMP;
|
||||
|
||||
return utf8;
|
||||
}
|
||||
|
||||
/* Recode an iso encoded string to UTF-8 */
|
||||
unsigned char* iso_decode(const unsigned char *iso, unsigned char *utf8,
|
||||
int cp, int count)
|
||||
static unsigned char* utf8encode_ex(unsigned long ucs, unsigned char *utf8, int* utf8_size)
|
||||
{
|
||||
const int tail = utf8_ucs_get_extra_bytes_count(ucs);
|
||||
*utf8_size -= tail + 1;
|
||||
return *utf8_size < 0 ? utf8 : utf8encode_internal(ucs, utf8, tail);
|
||||
}
|
||||
|
||||
/* Encode a UCS value as UTF-8 and return a pointer after this UTF-8 char. */
|
||||
unsigned char* utf8encode(unsigned long ucs, unsigned char *utf8)
|
||||
{
|
||||
return utf8encode_internal(ucs, utf8, utf8_ucs_get_extra_bytes_count(ucs));
|
||||
}
|
||||
|
||||
unsigned char* iso_decode(const unsigned char *iso, unsigned char *utf8, int cp, int count)
|
||||
{
|
||||
return iso_decode_ex(iso, utf8, cp, count, -1);
|
||||
}
|
||||
|
||||
/* Recode an iso encoded string to UTF-8 */
|
||||
unsigned char* iso_decode_ex(const unsigned char *iso, unsigned char *utf8, int cp, int count, int utf8_size)
|
||||
{
|
||||
if (utf8_size == -1)
|
||||
utf8_size = INT_MAX;
|
||||
|
||||
uint16_t *table = NULL;
|
||||
|
||||
cp_lock_enter();
|
||||
|
@ -322,11 +346,14 @@ unsigned char* iso_decode(const unsigned char *iso, unsigned char *utf8,
|
|||
|
||||
cp_lock_leave();
|
||||
|
||||
while (count--) {
|
||||
while (count-- && utf8_size > 0) {
|
||||
unsigned short ucs, tmp;
|
||||
|
||||
if (*iso < 128 || cp == UTF_8) /* Already UTF-8 */
|
||||
{
|
||||
*utf8++ = *iso++;
|
||||
--utf8_size;
|
||||
}
|
||||
|
||||
else {
|
||||
/* tid tells us which table to use and how */
|
||||
|
@ -375,7 +402,8 @@ unsigned char* iso_decode(const unsigned char *iso, unsigned char *utf8,
|
|||
|
||||
if (ucs == 0) /* unknown char, use replacement char */
|
||||
ucs = 0xfffd;
|
||||
utf8 = utf8encode(ucs, utf8);
|
||||
|
||||
utf8 = utf8encode_ex(ucs, utf8, &utf8_size);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue