Index: apps/misc.h =================================================================== --- apps/misc.h (revision 17152) +++ apps/misc.h (working copy) @@ -100,6 +100,8 @@ int get_replaygain_mode(bool have_track_gain, bool have_album_gain); #endif +int open_utf8(const char* pathname, int flags); + #ifdef BOOTFILE #if !defined(USB_NONE) && !defined(USB_IPODSTYLE) void check_bootfile(bool do_rolo); Index: apps/playlist.c =================================================================== --- apps/playlist.c (revision 17152) +++ apps/playlist.c (working copy) @@ -198,9 +198,6 @@ static const char playlist_thread_name[] = "playlist cachectrl"; #endif -#define BOM "\xef\xbb\xbf" -#define BOM_SIZE 3 - /* Check if the filename suggests M3U or M3U8 format. */ static bool is_m3u8(const char* filename) { @@ -210,11 +207,6 @@ return !(len > 4 && strcasecmp(&filename[len - 4], ".m3u") == 0); } -/* Check if a strings starts with an UTF-8 byte-order mark. */ -static bool is_utf8_bom(const char* str, int len) -{ - return len >= BOM_SIZE && memcmp(str, BOM, BOM_SIZE) == 0; -} /* Convert a filename in an M3U playlist to UTF-8. * @@ -534,9 +526,11 @@ int result = 0; if(-1 == playlist->fd) - playlist->fd = open(playlist->filename, O_RDONLY); + playlist->fd = open_utf8(playlist->filename, O_RDONLY); if(playlist->fd < 0) return -1; /* failure */ + if(lseek(playlist->fd, 0, SEEK_CUR) > 0) + playlist->utf8 = true; /* Override any earlier indication. */ gui_syncsplash(0, ID2P(LANG_WAIT)); @@ -564,14 +558,6 @@ p = (unsigned char *)buffer; - /* utf8 BOM at beginning of file? */ - if(i == 0 && is_utf8_bom(p, nread)) { - nread -= BOM_SIZE; - p += BOM_SIZE; - i += BOM_SIZE; - playlist->utf8 = true; /* Override any earlier indication. */ - } - for(count=0; count < nread; count++,p++) { /* Are we on a new line? */ @@ -2970,7 +2956,7 @@ return -1; } - fd = open(filename, O_RDONLY); + fd = open_utf8(filename, O_RDONLY); if (fd < 0) { gui_syncsplash(HZ*2, ID2P(LANG_PLAYLIST_ACCESS_ERROR)); @@ -3008,12 +2994,6 @@ if (action_userabort(TIMEOUT_NOBLOCK)) break; - if (count == 0 && is_utf8_bom(temp_buf, max)) - { - max -= BOM_SIZE; - memmove(temp_buf, temp_buf + BOM_SIZE, max); - } - if (temp_buf[0] != '#' && temp_buf[0] != '\0') { int insert_pos; @@ -3488,7 +3468,7 @@ { if (rename(path, playlist->filename) >= 0) { - playlist->fd = open(playlist->filename, O_RDONLY); + playlist->fd = open_utf8(playlist->filename, O_RDONLY); if (playlist->fd >= 0) { index = playlist->first_index; Index: apps/cuesheet.c =================================================================== --- apps/cuesheet.c (revision 17152) +++ apps/cuesheet.c (working copy) @@ -146,7 +146,7 @@ char *s; DEBUGF("cue parse\n"); - int fd = open(file,O_RDONLY); + int fd = open_utf8(file,O_RDONLY); if (fd < 0) { /* couln't open the file */ Index: apps/recorder/radio.c =================================================================== --- apps/recorder/radio.c (revision 17152) +++ apps/recorder/radio.c (working copy) @@ -1090,7 +1090,7 @@ snprintf(filepreset, sizeof(filepreset), "%s/%s.fmr", FMPRESET_PATH, filename); - fd = open(filepreset, O_RDONLY); + fd = open_utf8(filepreset, O_RDONLY); if(fd >= 0) { while(!done && num_presets < MAX_PRESETS) Index: apps/recorder/keyboard.c =================================================================== --- apps/recorder/keyboard.c (revision 17152) +++ apps/recorder/keyboard.c (working copy) @@ -143,7 +143,7 @@ return 0; } - fd = open(filename, O_RDONLY|O_BINARY); + fd = open_utf8(filename, O_RDONLY|O_BINARY); if (fd < 0) return 1; Index: apps/settings.c =================================================================== --- apps/settings.c (revision 17152) +++ apps/settings.c (working copy) @@ -265,7 +265,7 @@ char* name; char* value; int i; - fd = open(file, O_RDONLY); + fd = open_utf8(file, O_RDONLY); if (fd < 0) return false; Index: apps/gui/wps_parser.c =================================================================== --- apps/gui/wps_parser.c (revision 17152) +++ apps/gui/wps_parser.c (working copy) @@ -1452,19 +1452,6 @@ #endif /* HAVE_LCD_BITMAP */ -/* Skip leading UTF-8 BOM, if present. */ -static char *skip_utf8_bom(char *buf) -{ - unsigned char *s = (unsigned char *)buf; - - if(s[0] == 0xef && s[1] == 0xbb && s[2] == 0xbf) - { - buf += 3; - } - - return buf; -} - /* to setup up the wps-data from a format-buffer (isfile = false) from a (wps-)file (isfile = true)*/ bool wps_data_load(struct wps_data *wps_data, @@ -1522,7 +1509,7 @@ #endif #endif /* __PCTOOL__ */ - int fd = open(buf, O_RDONLY); + int fd = open_utf8(buf, O_RDONLY); if (fd < 0) return false; @@ -1557,9 +1544,6 @@ memset(bmp_names, 0, sizeof(bmp_names)); #endif - /* Skip leading UTF-8 BOM, if present. */ - wps_buffer = skip_utf8_bom(wps_buffer); - /* parse the WPS source */ if (!wps_parse(wps_data, wps_buffer)) { wps_reset(wps_data); Index: apps/misc.c =================================================================== --- apps/misc.c (revision 17152) +++ apps/misc.c (working copy) @@ -78,6 +78,9 @@ #endif #endif +#define BOM "\xef\xbb\xbf" +#define BOM_SIZE 3 + /* Format a large-range value for output, using the appropriate unit so that * the displayed value is in the range 1 <= display < 1000 (1024 for "binary" * units) if possible, and 3 significant digits are shown. If a buffer is @@ -1170,6 +1173,25 @@ } #endif /* !defined(__PCTOOL__) */ +/** @brief open a utf-8 file, set file descriptor to first byte. + * Skip BOM if present. Identical to open() otherwise + */ +int open_utf8(const char* pathname, int flags) +{ + int fd; + unsigned char bom[BOM_SIZE]; + + fd = open(pathname, flags); + if(fd < 0) return fd; + + read(fd, bom, BOM_SIZE); + /* check for BOM */ + if(memcmp(bom, BOM, BOM_SIZE)) + lseek(fd, 0, SEEK_SET); + return fd; +} + + #ifdef HAVE_LCD_COLOR /* * Helper function to convert a string of 6 hex digits to a native colour