diff options
-rw-r--r-- | apps/cuesheet.c | 2 | ||||
-rw-r--r-- | apps/gui/wps_parser.c | 18 | ||||
-rw-r--r-- | apps/misc.c | 31 | ||||
-rw-r--r-- | apps/misc.h | 6 | ||||
-rw-r--r-- | apps/playlist.c | 46 | ||||
-rw-r--r-- | apps/recorder/keyboard.c | 2 | ||||
-rw-r--r-- | apps/recorder/radio.c | 2 | ||||
-rw-r--r-- | apps/settings.c | 2 |
8 files changed, 55 insertions, 54 deletions
diff --git a/apps/cuesheet.c b/apps/cuesheet.c index 853a2a0f95..5583264ab9 100644 --- a/apps/cuesheet.c +++ b/apps/cuesheet.c | |||
@@ -147,7 +147,7 @@ bool parse_cuesheet(char *file, struct cuesheet *cue) | |||
147 | char *s; | 147 | char *s; |
148 | 148 | ||
149 | DEBUGF("cue parse\n"); | 149 | DEBUGF("cue parse\n"); |
150 | int fd = open(file,O_RDONLY); | 150 | int fd = open_utf8(file,O_RDONLY); |
151 | if (fd < 0) | 151 | if (fd < 0) |
152 | { | 152 | { |
153 | /* couln't open the file */ | 153 | /* couln't open the file */ |
diff --git a/apps/gui/wps_parser.c b/apps/gui/wps_parser.c index 88a237cb0f..714c419af1 100644 --- a/apps/gui/wps_parser.c +++ b/apps/gui/wps_parser.c | |||
@@ -1527,19 +1527,6 @@ static bool load_wps_bitmaps(struct wps_data *wps_data, char *bmpdir) | |||
1527 | 1527 | ||
1528 | #endif /* HAVE_LCD_BITMAP */ | 1528 | #endif /* HAVE_LCD_BITMAP */ |
1529 | 1529 | ||
1530 | /* Skip leading UTF-8 BOM, if present. */ | ||
1531 | static char *skip_utf8_bom(char *buf) | ||
1532 | { | ||
1533 | unsigned char *s = (unsigned char *)buf; | ||
1534 | |||
1535 | if(s[0] == 0xef && s[1] == 0xbb && s[2] == 0xbf) | ||
1536 | { | ||
1537 | buf += 3; | ||
1538 | } | ||
1539 | |||
1540 | return buf; | ||
1541 | } | ||
1542 | |||
1543 | /* to setup up the wps-data from a format-buffer (isfile = false) | 1530 | /* to setup up the wps-data from a format-buffer (isfile = false) |
1544 | from a (wps-)file (isfile = true)*/ | 1531 | from a (wps-)file (isfile = true)*/ |
1545 | bool wps_data_load(struct wps_data *wps_data, | 1532 | bool wps_data_load(struct wps_data *wps_data, |
@@ -1604,7 +1591,7 @@ bool wps_data_load(struct wps_data *wps_data, | |||
1604 | #endif | 1591 | #endif |
1605 | #endif /* __PCTOOL__ */ | 1592 | #endif /* __PCTOOL__ */ |
1606 | 1593 | ||
1607 | int fd = open(buf, O_RDONLY); | 1594 | int fd = open_utf8(buf, O_RDONLY); |
1608 | 1595 | ||
1609 | if (fd < 0) | 1596 | if (fd < 0) |
1610 | return false; | 1597 | return false; |
@@ -1639,9 +1626,6 @@ bool wps_data_load(struct wps_data *wps_data, | |||
1639 | memset(bmp_names, 0, sizeof(bmp_names)); | 1626 | memset(bmp_names, 0, sizeof(bmp_names)); |
1640 | #endif | 1627 | #endif |
1641 | 1628 | ||
1642 | /* Skip leading UTF-8 BOM, if present. */ | ||
1643 | wps_buffer = skip_utf8_bom(wps_buffer); | ||
1644 | |||
1645 | /* parse the WPS source */ | 1629 | /* parse the WPS source */ |
1646 | if (!wps_parse(wps_data, wps_buffer)) { | 1630 | if (!wps_parse(wps_data, wps_buffer)) { |
1647 | wps_reset(wps_data); | 1631 | wps_reset(wps_data); |
diff --git a/apps/misc.c b/apps/misc.c index 60955b9820..f1f5c4aa12 100644 --- a/apps/misc.c +++ b/apps/misc.c | |||
@@ -1154,7 +1154,7 @@ char *strip_extension(char* buffer, int buffer_size, const char *filename) | |||
1154 | { | 1154 | { |
1155 | char *dot = strrchr(filename, '.'); | 1155 | char *dot = strrchr(filename, '.'); |
1156 | int len; | 1156 | int len; |
1157 | 1157 | ||
1158 | if (buffer_size <= 0) | 1158 | if (buffer_size <= 0) |
1159 | { | 1159 | { |
1160 | return NULL; | 1160 | return NULL; |
@@ -1180,6 +1180,35 @@ char *strip_extension(char* buffer, int buffer_size, const char *filename) | |||
1180 | } | 1180 | } |
1181 | #endif /* !defined(__PCTOOL__) */ | 1181 | #endif /* !defined(__PCTOOL__) */ |
1182 | 1182 | ||
1183 | /** Open a UTF-8 file and set file descriptor to first byte after BOM. | ||
1184 | * If no BOM is present this behaves like open(). | ||
1185 | * If the file is opened for writing and O_TRUNC is set, write a BOM to | ||
1186 | * the opened file and leave the file pointer set after the BOM. | ||
1187 | */ | ||
1188 | int open_utf8(const char* pathname, int flags) | ||
1189 | { | ||
1190 | int fd; | ||
1191 | unsigned char bom[BOM_SIZE]; | ||
1192 | |||
1193 | fd = open(pathname, flags); | ||
1194 | if(fd < 0) | ||
1195 | return fd; | ||
1196 | |||
1197 | if(flags & (O_TRUNC | O_WRONLY)) | ||
1198 | { | ||
1199 | write(fd, BOM, BOM_SIZE); | ||
1200 | } | ||
1201 | else | ||
1202 | { | ||
1203 | read(fd, bom, BOM_SIZE); | ||
1204 | /* check for BOM */ | ||
1205 | if(memcmp(bom, BOM, BOM_SIZE)) | ||
1206 | lseek(fd, 0, SEEK_SET); | ||
1207 | } | ||
1208 | return fd; | ||
1209 | } | ||
1210 | |||
1211 | |||
1183 | #ifdef HAVE_LCD_COLOR | 1212 | #ifdef HAVE_LCD_COLOR |
1184 | /* | 1213 | /* |
1185 | * Helper function to convert a string of 6 hex digits to a native colour | 1214 | * Helper function to convert a string of 6 hex digits to a native colour |
diff --git a/apps/misc.h b/apps/misc.h index 160d74473f..b5547ec38f 100644 --- a/apps/misc.h +++ b/apps/misc.h | |||
@@ -23,6 +23,10 @@ | |||
23 | 23 | ||
24 | #include <stdbool.h> | 24 | #include <stdbool.h> |
25 | #include <inttypes.h> | 25 | #include <inttypes.h> |
26 | |||
27 | #define BOM "\xef\xbb\xbf" | ||
28 | #define BOM_SIZE 3 | ||
29 | |||
26 | /* Format a large-range value for output, using the appropriate unit so that | 30 | /* Format a large-range value for output, using the appropriate unit so that |
27 | * the displayed value is in the range 1 <= display < 1000 (1024 for "binary" | 31 | * the displayed value is in the range 1 <= display < 1000 (1024 for "binary" |
28 | * units) if possible, and 3 significant digits are shown. If a buffer is | 32 | * units) if possible, and 3 significant digits are shown. If a buffer is |
@@ -106,6 +110,8 @@ extern int show_logo(void); | |||
106 | int get_replaygain_mode(bool have_track_gain, bool have_album_gain); | 110 | int get_replaygain_mode(bool have_track_gain, bool have_album_gain); |
107 | #endif | 111 | #endif |
108 | 112 | ||
113 | int open_utf8(const char* pathname, int flags); | ||
114 | |||
109 | #ifdef BOOTFILE | 115 | #ifdef BOOTFILE |
110 | #if !defined(USB_NONE) && !defined(USB_IPODSTYLE) | 116 | #if !defined(USB_NONE) && !defined(USB_IPODSTYLE) |
111 | void check_bootfile(bool do_rolo); | 117 | void check_bootfile(bool do_rolo); |
diff --git a/apps/playlist.c b/apps/playlist.c index f6d536fa25..b42ecb5681 100644 --- a/apps/playlist.c +++ b/apps/playlist.c | |||
@@ -200,9 +200,6 @@ static long playlist_stack[(DEFAULT_STACK_SIZE + 0x800)/sizeof(long)]; | |||
200 | static const char playlist_thread_name[] = "playlist cachectrl"; | 200 | static const char playlist_thread_name[] = "playlist cachectrl"; |
201 | #endif | 201 | #endif |
202 | 202 | ||
203 | #define BOM "\xef\xbb\xbf" | ||
204 | #define BOM_SIZE 3 | ||
205 | |||
206 | /* Check if the filename suggests M3U or M3U8 format. */ | 203 | /* Check if the filename suggests M3U or M3U8 format. */ |
207 | static bool is_m3u8(const char* filename) | 204 | static bool is_m3u8(const char* filename) |
208 | { | 205 | { |
@@ -212,11 +209,6 @@ static bool is_m3u8(const char* filename) | |||
212 | return !(len > 4 && strcasecmp(&filename[len - 4], ".m3u") == 0); | 209 | return !(len > 4 && strcasecmp(&filename[len - 4], ".m3u") == 0); |
213 | } | 210 | } |
214 | 211 | ||
215 | /* Check if a strings starts with an UTF-8 byte-order mark. */ | ||
216 | static bool is_utf8_bom(const char* str, int len) | ||
217 | { | ||
218 | return len >= BOM_SIZE && memcmp(str, BOM, BOM_SIZE) == 0; | ||
219 | } | ||
220 | 212 | ||
221 | /* Convert a filename in an M3U playlist to UTF-8. | 213 | /* Convert a filename in an M3U playlist to UTF-8. |
222 | * | 214 | * |
@@ -538,9 +530,11 @@ static int add_indices_to_playlist(struct playlist_info* playlist, | |||
538 | int result = 0; | 530 | int result = 0; |
539 | 531 | ||
540 | if(-1 == playlist->fd) | 532 | if(-1 == playlist->fd) |
541 | playlist->fd = open(playlist->filename, O_RDONLY); | 533 | playlist->fd = open_utf8(playlist->filename, O_RDONLY); |
542 | if(playlist->fd < 0) | 534 | if(playlist->fd < 0) |
543 | return -1; /* failure */ | 535 | return -1; /* failure */ |
536 | if(lseek(playlist->fd, 0, SEEK_CUR) > 0) | ||
537 | playlist->utf8 = true; /* Override any earlier indication. */ | ||
544 | 538 | ||
545 | gui_syncsplash(0, ID2P(LANG_WAIT)); | 539 | gui_syncsplash(0, ID2P(LANG_WAIT)); |
546 | 540 | ||
@@ -568,14 +562,6 @@ static int add_indices_to_playlist(struct playlist_info* playlist, | |||
568 | 562 | ||
569 | p = (unsigned char *)buffer; | 563 | p = (unsigned char *)buffer; |
570 | 564 | ||
571 | /* utf8 BOM at beginning of file? */ | ||
572 | if(i == 0 && is_utf8_bom(p, nread)) { | ||
573 | nread -= BOM_SIZE; | ||
574 | p += BOM_SIZE; | ||
575 | i += BOM_SIZE; | ||
576 | playlist->utf8 = true; /* Override any earlier indication. */ | ||
577 | } | ||
578 | |||
579 | for(count=0; count < nread; count++,p++) { | 565 | for(count=0; count < nread; count++,p++) { |
580 | 566 | ||
581 | /* Are we on a new line? */ | 567 | /* Are we on a new line? */ |
@@ -2972,7 +2958,7 @@ int playlist_insert_playlist(struct playlist_info* playlist, const char *filenam | |||
2972 | return -1; | 2958 | return -1; |
2973 | } | 2959 | } |
2974 | 2960 | ||
2975 | fd = open(filename, O_RDONLY); | 2961 | fd = open_utf8(filename, O_RDONLY); |
2976 | if (fd < 0) | 2962 | if (fd < 0) |
2977 | { | 2963 | { |
2978 | gui_syncsplash(HZ*2, ID2P(LANG_PLAYLIST_ACCESS_ERROR)); | 2964 | gui_syncsplash(HZ*2, ID2P(LANG_PLAYLIST_ACCESS_ERROR)); |
@@ -3010,12 +2996,6 @@ int playlist_insert_playlist(struct playlist_info* playlist, const char *filenam | |||
3010 | if (action_userabort(TIMEOUT_NOBLOCK)) | 2996 | if (action_userabort(TIMEOUT_NOBLOCK)) |
3011 | break; | 2997 | break; |
3012 | 2998 | ||
3013 | if (count == 0 && is_utf8_bom(temp_buf, max)) | ||
3014 | { | ||
3015 | max -= BOM_SIZE; | ||
3016 | memmove(temp_buf, temp_buf + BOM_SIZE, max); | ||
3017 | } | ||
3018 | |||
3019 | if (temp_buf[0] != '#' && temp_buf[0] != '\0') | 2999 | if (temp_buf[0] != '#' && temp_buf[0] != '\0') |
3020 | { | 3000 | { |
3021 | int insert_pos; | 3001 | int insert_pos; |
@@ -3413,7 +3393,15 @@ int playlist_save(struct playlist_info* playlist, char *filename) | |||
3413 | overwrite_current = true; | 3393 | overwrite_current = true; |
3414 | } | 3394 | } |
3415 | 3395 | ||
3416 | fd = open(path, O_CREAT|O_WRONLY|O_TRUNC); | 3396 | if (is_m3u8(path)) |
3397 | { | ||
3398 | fd = open_utf8(path, O_CREAT|O_WRONLY|O_TRUNC); | ||
3399 | } | ||
3400 | else | ||
3401 | { | ||
3402 | /* some applications require a BOM to read the file properly */ | ||
3403 | fd = open(path, O_CREAT|O_WRONLY|O_TRUNC); | ||
3404 | } | ||
3417 | if (fd < 0) | 3405 | if (fd < 0) |
3418 | { | 3406 | { |
3419 | gui_syncsplash(HZ*2, ID2P(LANG_PLAYLIST_ACCESS_ERROR)); | 3407 | gui_syncsplash(HZ*2, ID2P(LANG_PLAYLIST_ACCESS_ERROR)); |
@@ -3423,12 +3411,6 @@ int playlist_save(struct playlist_info* playlist, char *filename) | |||
3423 | display_playlist_count(count, ID2P(LANG_PLAYLIST_SAVE_COUNT), false); | 3411 | display_playlist_count(count, ID2P(LANG_PLAYLIST_SAVE_COUNT), false); |
3424 | 3412 | ||
3425 | cpu_boost(true); | 3413 | cpu_boost(true); |
3426 | |||
3427 | if (is_m3u8(path)) | ||
3428 | { | ||
3429 | /* some applications require a BOM to read the file properly */ | ||
3430 | write(fd, BOM, BOM_SIZE); | ||
3431 | } | ||
3432 | 3414 | ||
3433 | index = playlist->first_index; | 3415 | index = playlist->first_index; |
3434 | for (i=0; i<playlist->amount; i++) | 3416 | for (i=0; i<playlist->amount; i++) |
@@ -3496,7 +3478,7 @@ int playlist_save(struct playlist_info* playlist, char *filename) | |||
3496 | { | 3478 | { |
3497 | if (rename(path, playlist->filename) >= 0) | 3479 | if (rename(path, playlist->filename) >= 0) |
3498 | { | 3480 | { |
3499 | playlist->fd = open(playlist->filename, O_RDONLY); | 3481 | playlist->fd = open_utf8(playlist->filename, O_RDONLY); |
3500 | if (playlist->fd >= 0) | 3482 | if (playlist->fd >= 0) |
3501 | { | 3483 | { |
3502 | index = playlist->first_index; | 3484 | index = playlist->first_index; |
diff --git a/apps/recorder/keyboard.c b/apps/recorder/keyboard.c index a15b4cc346..621ec4e1c3 100644 --- a/apps/recorder/keyboard.c +++ b/apps/recorder/keyboard.c | |||
@@ -141,7 +141,7 @@ int load_kbd(unsigned char* filename) | |||
141 | return 0; | 141 | return 0; |
142 | } | 142 | } |
143 | 143 | ||
144 | fd = open(filename, O_RDONLY|O_BINARY); | 144 | fd = open_utf8(filename, O_RDONLY|O_BINARY); |
145 | if (fd < 0) | 145 | if (fd < 0) |
146 | return 1; | 146 | return 1; |
147 | 147 | ||
diff --git a/apps/recorder/radio.c b/apps/recorder/radio.c index bd91defe09..145972939e 100644 --- a/apps/recorder/radio.c +++ b/apps/recorder/radio.c | |||
@@ -1112,7 +1112,7 @@ void radio_load_presets(char *filename) | |||
1112 | snprintf(filepreset, sizeof(filepreset), "%s/%s.fmr", | 1112 | snprintf(filepreset, sizeof(filepreset), "%s/%s.fmr", |
1113 | FMPRESET_PATH, filename); | 1113 | FMPRESET_PATH, filename); |
1114 | 1114 | ||
1115 | fd = open(filepreset, O_RDONLY); | 1115 | fd = open_utf8(filepreset, O_RDONLY); |
1116 | if(fd >= 0) | 1116 | if(fd >= 0) |
1117 | { | 1117 | { |
1118 | while(!done && num_presets < MAX_PRESETS) | 1118 | while(!done && num_presets < MAX_PRESETS) |
diff --git a/apps/settings.c b/apps/settings.c index 4c181593db..a9257aaf53 100644 --- a/apps/settings.c +++ b/apps/settings.c | |||
@@ -265,7 +265,7 @@ bool settings_load_config(const char* file, bool apply) | |||
265 | char* name; | 265 | char* name; |
266 | char* value; | 266 | char* value; |
267 | int i; | 267 | int i; |
268 | fd = open(file, O_RDONLY); | 268 | fd = open_utf8(file, O_RDONLY); |
269 | if (fd < 0) | 269 | if (fd < 0) |
270 | return false; | 270 | return false; |
271 | 271 | ||