diff options
author | Nicolas Pennequin <nicolas.pennequin@free.fr> | 2007-11-14 22:02:41 +0000 |
---|---|---|
committer | Nicolas Pennequin <nicolas.pennequin@free.fr> | 2007-11-14 22:02:41 +0000 |
commit | 31f76116f1b3188eb15a1b2caaa445d1770efb30 (patch) | |
tree | 50d0ddd6190f6cd96f033981ddb0fba301432b22 | |
parent | 7ddefe2a5d6ef10463cc26262d37f54a490b1afb (diff) | |
download | rockbox-31f76116f1b3188eb15a1b2caaa445d1770efb30.tar.gz rockbox-31f76116f1b3188eb15a1b2caaa445d1770efb30.zip |
Make the WPS parser stricter with invalid parameter lists. It will now reject them instead of ignoring them (this includes the second parameter to %m|x|, which is invalid and now causes a failure). Also change the debugging code in order to allow more precise error messages, including the faulty token's index and description. Finally, add a few missing token description and fine-tune the #ifdefs.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@15624 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r-- | apps/gui/gwps.h | 4 | ||||
-rw-r--r-- | apps/gui/wps_debug.c | 714 | ||||
-rw-r--r-- | apps/gui/wps_parser.c | 129 |
3 files changed, 483 insertions, 364 deletions
diff --git a/apps/gui/gwps.h b/apps/gui/gwps.h index 31f58ee408..56c8a6da6d 100644 --- a/apps/gui/gwps.h +++ b/apps/gui/gwps.h | |||
@@ -180,9 +180,11 @@ enum wps_token_type { | |||
180 | WPS_TOKEN_CONDITIONAL_END, | 180 | WPS_TOKEN_CONDITIONAL_END, |
181 | 181 | ||
182 | /* Database */ | 182 | /* Database */ |
183 | #ifdef HAVE_TAGCACHE | ||
183 | WPS_TOKEN_DATABASE_PLAYCOUNT, | 184 | WPS_TOKEN_DATABASE_PLAYCOUNT, |
184 | WPS_TOKEN_DATABASE_RATING, | 185 | WPS_TOKEN_DATABASE_RATING, |
185 | WPS_TOKEN_DATABASE_AUTOSCORE, | 186 | WPS_TOKEN_DATABASE_AUTOSCORE, |
187 | #endif | ||
186 | 188 | ||
187 | /* File */ | 189 | /* File */ |
188 | WPS_TOKEN_FILE_BITRATE, | 190 | WPS_TOKEN_FILE_BITRATE, |
@@ -237,7 +239,9 @@ enum wps_token_type { | |||
237 | 239 | ||
238 | /* Progressbar */ | 240 | /* Progressbar */ |
239 | WPS_TOKEN_PROGRESSBAR, | 241 | WPS_TOKEN_PROGRESSBAR, |
242 | #ifdef HAVE_LCD_CHARCELLS | ||
240 | WPS_TOKEN_PLAYER_PROGRESSBAR, | 243 | WPS_TOKEN_PLAYER_PROGRESSBAR, |
244 | #endif | ||
241 | 245 | ||
242 | #ifdef HAVE_LCD_BITMAP | 246 | #ifdef HAVE_LCD_BITMAP |
243 | /* Peakmeter */ | 247 | /* Peakmeter */ |
diff --git a/apps/gui/wps_debug.c b/apps/gui/wps_debug.c index 6b7b988321..9443f23730 100644 --- a/apps/gui/wps_debug.c +++ b/apps/gui/wps_debug.c | |||
@@ -28,9 +28,10 @@ | |||
28 | #include "debug.h" | 28 | #include "debug.h" |
29 | #endif | 29 | #endif |
30 | 30 | ||
31 | #define PARSE_FAIL_UNCLOSED_COND 1 | 31 | #define PARSE_FAIL_UNCLOSED_COND 1 |
32 | #define PARSE_FAIL_INVALID_CHAR 2 | 32 | #define PARSE_FAIL_INVALID_CHAR 2 |
33 | #define PARSE_FAIL_COND_SYNTAX_ERROR 3 | 33 | #define PARSE_FAIL_COND_SYNTAX_ERROR 3 |
34 | #define PARSE_FAIL_COND_INVALID_PARAM 4 | ||
34 | 35 | ||
35 | #if defined(SIMULATOR) || defined(__PCTOOL__) | 36 | #if defined(SIMULATOR) || defined(__PCTOOL__) |
36 | extern bool debug_wps; | 37 | extern bool debug_wps; |
@@ -41,368 +42,431 @@ static char *next_str(bool next) { | |||
41 | return next ? "next " : ""; | 42 | return next ? "next " : ""; |
42 | } | 43 | } |
43 | 44 | ||
44 | static void dump_wps_tokens(struct wps_data *data) | 45 | static char *get_token_desc(struct wps_token *token, struct wps_data *data, |
46 | char *buf, int bufsize) | ||
45 | { | 47 | { |
46 | struct wps_token *token; | 48 | bool next = token->next; |
47 | int i, j; | ||
48 | int indent = 0; | ||
49 | char buf[64]; | ||
50 | bool next; | ||
51 | int num_string_tokens = 0; | ||
52 | |||
53 | /* Dump parsed WPS */ | ||
54 | for (i = 0, token = data->tokens; i < data->num_tokens; i++, token++) { | ||
55 | next = token->next; | ||
56 | |||
57 | switch(token->type) { | ||
58 | case WPS_TOKEN_UNKNOWN: | ||
59 | snprintf(buf, sizeof(buf), "Unknown token"); | ||
60 | break; | ||
61 | case WPS_TOKEN_CHARACTER: | ||
62 | snprintf(buf, sizeof(buf), "Character '%c'", | ||
63 | token->value.c); | ||
64 | break; | ||
65 | 49 | ||
66 | case WPS_TOKEN_STRING: | 50 | switch(token->type) |
67 | snprintf(buf, sizeof(buf), "String '%s'", | 51 | { |
68 | data->strings[token->value.i]); | 52 | case WPS_NO_TOKEN: |
69 | num_string_tokens++; | 53 | snprintf(buf, bufsize, "No token"); |
70 | break; | 54 | break; |
71 | 55 | ||
72 | #ifdef HAVE_LCD_BITMAP | 56 | case WPS_TOKEN_UNKNOWN: |
73 | case WPS_TOKEN_ALIGN_LEFT: | 57 | snprintf(buf, bufsize, "Unknown token"); |
74 | snprintf(buf, sizeof(buf), "align left"); | 58 | break; |
75 | break; | ||
76 | 59 | ||
77 | case WPS_TOKEN_ALIGN_CENTER: | 60 | case WPS_TOKEN_CHARACTER: |
78 | snprintf(buf, sizeof(buf), "align center"); | 61 | snprintf(buf, bufsize, "Character '%c'", |
79 | break; | 62 | token->value.c); |
63 | break; | ||
80 | 64 | ||
81 | case WPS_TOKEN_ALIGN_RIGHT: | 65 | case WPS_TOKEN_STRING: |
82 | snprintf(buf, sizeof(buf), "align right"); | 66 | snprintf(buf, bufsize, "String '%s'", |
83 | break; | 67 | data->strings[token->value.i]); |
68 | break; | ||
84 | 69 | ||
85 | case WPS_TOKEN_LEFTMARGIN: | 70 | #ifdef HAVE_LCD_BITMAP |
86 | snprintf(buf, sizeof(buf), "left margin, value: %d", | 71 | case WPS_TOKEN_ALIGN_LEFT: |
87 | token->value.i); | 72 | snprintf(buf, bufsize, "align left"); |
88 | break; | 73 | break; |
74 | |||
75 | case WPS_TOKEN_ALIGN_CENTER: | ||
76 | snprintf(buf, bufsize, "align center"); | ||
77 | break; | ||
78 | |||
79 | case WPS_TOKEN_ALIGN_RIGHT: | ||
80 | snprintf(buf, bufsize, "align right"); | ||
81 | break; | ||
82 | |||
83 | case WPS_TOKEN_LEFTMARGIN: | ||
84 | snprintf(buf, bufsize, "left margin, value: %d", | ||
85 | token->value.i); | ||
86 | break; | ||
89 | #endif | 87 | #endif |
90 | 88 | ||
91 | case WPS_TOKEN_SUBLINE_TIMEOUT: | 89 | case WPS_TOKEN_SUBLINE_TIMEOUT: |
92 | snprintf(buf, sizeof(buf), "subline timeout value: %d", | 90 | snprintf(buf, bufsize, "subline timeout value: %d", |
93 | token->value.i); | 91 | token->value.i); |
94 | break; | 92 | break; |
95 | 93 | ||
96 | case WPS_TOKEN_CONDITIONAL: | 94 | case WPS_TOKEN_CONDITIONAL: |
97 | snprintf(buf, sizeof(buf), "conditional, %d options", | 95 | snprintf(buf, bufsize, "conditional, %d options", |
98 | token->value.i); | 96 | token->value.i); |
99 | break; | 97 | break; |
100 | 98 | ||
101 | case WPS_TOKEN_CONDITIONAL_START: | 99 | case WPS_TOKEN_CONDITIONAL_START: |
102 | snprintf(buf, sizeof(buf), "conditional start, next cond: %d", | 100 | snprintf(buf, bufsize, "conditional start, next cond: %d", |
103 | token->value.i); | 101 | token->value.i); |
104 | indent++; | 102 | break; |
105 | break; | ||
106 | 103 | ||
107 | case WPS_TOKEN_CONDITIONAL_OPTION: | 104 | case WPS_TOKEN_CONDITIONAL_OPTION: |
108 | snprintf(buf, sizeof(buf), "conditional option, next cond: %d", | 105 | snprintf(buf, bufsize, "conditional option, next cond: %d", |
109 | token->value.i); | 106 | token->value.i); |
110 | break; | 107 | break; |
111 | 108 | ||
112 | case WPS_TOKEN_CONDITIONAL_END: | 109 | case WPS_TOKEN_CONDITIONAL_END: |
113 | snprintf(buf, sizeof(buf), "conditional end"); | 110 | snprintf(buf, bufsize, "conditional end"); |
114 | indent--; | 111 | break; |
115 | break; | ||
116 | 112 | ||
117 | #ifdef HAVE_LCD_BITMAP | 113 | #ifdef HAVE_LCD_BITMAP |
118 | case WPS_TOKEN_IMAGE_PRELOAD: | 114 | case WPS_TOKEN_IMAGE_PRELOAD: |
119 | snprintf(buf, sizeof(buf), "preload image"); | 115 | snprintf(buf, bufsize, "preload image"); |
120 | break; | 116 | break; |
121 | 117 | ||
122 | case WPS_TOKEN_IMAGE_PRELOAD_DISPLAY: | 118 | case WPS_TOKEN_IMAGE_PRELOAD_DISPLAY: |
123 | snprintf(buf, sizeof(buf), "display preloaded image %d", | 119 | snprintf(buf, bufsize, "display preloaded image %d", |
124 | token->value.i); | 120 | token->value.i); |
125 | break; | 121 | break; |
126 | 122 | ||
127 | case WPS_TOKEN_IMAGE_DISPLAY: | 123 | case WPS_TOKEN_IMAGE_DISPLAY: |
128 | snprintf(buf, sizeof(buf), "display image"); | 124 | snprintf(buf, bufsize, "display image"); |
129 | break; | 125 | break; |
130 | #endif | 126 | #endif |
131 | 127 | ||
132 | #ifdef HAS_BUTTON_HOLD | 128 | #ifdef HAS_BUTTON_HOLD |
133 | case WPS_TOKEN_MAIN_HOLD: | 129 | case WPS_TOKEN_MAIN_HOLD: |
134 | snprintf(buf, sizeof(buf), "mode hold"); | 130 | snprintf(buf, bufsize, "mode hold"); |
135 | break; | 131 | break; |
136 | #endif | 132 | #endif |
137 | 133 | ||
138 | #ifdef HAS_REMOTE_BUTTON_HOLD | 134 | #ifdef HAS_REMOTE_BUTTON_HOLD |
139 | case WPS_TOKEN_REMOTE_HOLD: | 135 | case WPS_TOKEN_REMOTE_HOLD: |
140 | snprintf(buf, sizeof(buf), "mode remote hold"); | 136 | snprintf(buf, bufsize, "mode remote hold"); |
141 | break; | 137 | break; |
142 | #endif | 138 | #endif |
143 | 139 | ||
144 | case WPS_TOKEN_REPEAT_MODE: | 140 | case WPS_TOKEN_REPEAT_MODE: |
145 | snprintf(buf, sizeof(buf), "mode repeat"); | 141 | snprintf(buf, bufsize, "mode repeat"); |
146 | break; | 142 | break; |
147 | 143 | ||
148 | case WPS_TOKEN_PLAYBACK_STATUS: | 144 | case WPS_TOKEN_PLAYBACK_STATUS: |
149 | snprintf(buf, sizeof(buf), "mode playback"); | 145 | snprintf(buf, bufsize, "mode playback"); |
150 | break; | 146 | break; |
151 | 147 | ||
152 | case WPS_TOKEN_RTC_DAY_OF_MONTH: | 148 | case WPS_TOKEN_RTC_DAY_OF_MONTH: |
153 | snprintf(buf, sizeof(buf), "rtc: day of month (01..31)"); | 149 | snprintf(buf, bufsize, "rtc: day of month (01..31)"); |
154 | break; | 150 | break; |
155 | case WPS_TOKEN_RTC_DAY_OF_MONTH_BLANK_PADDED: | 151 | case WPS_TOKEN_RTC_DAY_OF_MONTH_BLANK_PADDED: |
156 | snprintf(buf, sizeof(buf), | 152 | snprintf(buf, bufsize, |
157 | "rtc: day of month, blank padded ( 1..31)"); | 153 | "rtc: day of month, blank padded ( 1..31)"); |
158 | break; | 154 | break; |
159 | case WPS_TOKEN_RTC_HOUR_24_ZERO_PADDED: | 155 | case WPS_TOKEN_RTC_HOUR_24_ZERO_PADDED: |
160 | snprintf(buf, sizeof(buf), "rtc: hour (00..23)"); | 156 | snprintf(buf, bufsize, "rtc: hour (00..23)"); |
161 | break; | 157 | break; |
162 | case WPS_TOKEN_RTC_HOUR_24: | 158 | case WPS_TOKEN_RTC_HOUR_24: |
163 | snprintf(buf, sizeof(buf), "rtc: hour ( 0..23)"); | 159 | snprintf(buf, bufsize, "rtc: hour ( 0..23)"); |
164 | break; | 160 | break; |
165 | case WPS_TOKEN_RTC_HOUR_12_ZERO_PADDED: | 161 | case WPS_TOKEN_RTC_HOUR_12_ZERO_PADDED: |
166 | snprintf(buf, sizeof(buf), "rtc: hour (01..12)"); | 162 | snprintf(buf, bufsize, "rtc: hour (01..12)"); |
167 | break; | 163 | break; |
168 | case WPS_TOKEN_RTC_HOUR_12: | 164 | case WPS_TOKEN_RTC_HOUR_12: |
169 | snprintf(buf, sizeof(buf), "rtc: hour ( 1..12)"); | 165 | snprintf(buf, bufsize, "rtc: hour ( 1..12)"); |
170 | break; | 166 | break; |
171 | case WPS_TOKEN_RTC_MONTH: | 167 | case WPS_TOKEN_RTC_MONTH: |
172 | snprintf(buf, sizeof(buf), "rtc: month (01..12)"); | 168 | snprintf(buf, bufsize, "rtc: month (01..12)"); |
173 | break; | 169 | break; |
174 | case WPS_TOKEN_RTC_MINUTE: | 170 | case WPS_TOKEN_RTC_MINUTE: |
175 | snprintf(buf, sizeof(buf), "rtc: minute (00..59)"); | 171 | snprintf(buf, bufsize, "rtc: minute (00..59)"); |
176 | break; | 172 | break; |
177 | case WPS_TOKEN_RTC_SECOND: | 173 | case WPS_TOKEN_RTC_SECOND: |
178 | snprintf(buf, sizeof(buf), "rtc: second (00..59)"); | 174 | snprintf(buf, bufsize, "rtc: second (00..59)"); |
179 | break; | 175 | break; |
180 | case WPS_TOKEN_RTC_YEAR_2_DIGITS: | 176 | case WPS_TOKEN_RTC_YEAR_2_DIGITS: |
181 | snprintf(buf, sizeof(buf), | 177 | snprintf(buf, bufsize, |
182 | "rtc: last two digits of year (00..99)"); | 178 | "rtc: last two digits of year (00..99)"); |
183 | break; | 179 | break; |
184 | case WPS_TOKEN_RTC_YEAR_4_DIGITS: | 180 | case WPS_TOKEN_RTC_YEAR_4_DIGITS: |
185 | snprintf(buf, sizeof(buf), "rtc: year (1970...)"); | 181 | snprintf(buf, bufsize, "rtc: year (1970...)"); |
186 | break; | 182 | break; |
187 | case WPS_TOKEN_RTC_AM_PM_UPPER: | 183 | case WPS_TOKEN_RTC_AM_PM_UPPER: |
188 | snprintf(buf, sizeof(buf), | 184 | snprintf(buf, bufsize, |
189 | "rtc: upper case AM or PM indicator"); | 185 | "rtc: upper case AM or PM indicator"); |
190 | break; | 186 | break; |
191 | case WPS_TOKEN_RTC_AM_PM_LOWER: | 187 | case WPS_TOKEN_RTC_AM_PM_LOWER: |
192 | snprintf(buf, sizeof(buf), | 188 | snprintf(buf, bufsize, |
193 | "rtc: lower case am or pm indicator"); | 189 | "rtc: lower case am or pm indicator"); |
194 | break; | 190 | break; |
195 | case WPS_TOKEN_RTC_WEEKDAY_NAME: | 191 | case WPS_TOKEN_RTC_WEEKDAY_NAME: |
196 | snprintf(buf, sizeof(buf), | 192 | snprintf(buf, bufsize, |
197 | "rtc: abbreviated weekday name (Sun..Sat)"); | 193 | "rtc: abbreviated weekday name (Sun..Sat)"); |
198 | break; | 194 | break; |
199 | case WPS_TOKEN_RTC_MONTH_NAME: | 195 | case WPS_TOKEN_RTC_MONTH_NAME: |
200 | snprintf(buf, sizeof(buf), | 196 | snprintf(buf, bufsize, |
201 | "rtc: abbreviated month name (Jan..Dec)"); | 197 | "rtc: abbreviated month name (Jan..Dec)"); |
202 | break; | 198 | break; |
203 | case WPS_TOKEN_RTC_DAY_OF_WEEK_START_MON: | 199 | case WPS_TOKEN_RTC_DAY_OF_WEEK_START_MON: |
204 | snprintf(buf, sizeof(buf), | 200 | snprintf(buf, bufsize, |
205 | "rtc: day of week (1..7); 1 is Monday"); | 201 | "rtc: day of week (1..7); 1 is Monday"); |
206 | break; | 202 | break; |
207 | case WPS_TOKEN_RTC_DAY_OF_WEEK_START_SUN: | 203 | case WPS_TOKEN_RTC_DAY_OF_WEEK_START_SUN: |
208 | snprintf(buf, sizeof(buf), | 204 | snprintf(buf, bufsize, |
209 | "rtc: day of week (0..6); 0 is Sunday"); | 205 | "rtc: day of week (0..6); 0 is Sunday"); |
210 | break; | 206 | break; |
211 | 207 | ||
212 | #if (CONFIG_CODEC == SWCODEC) | 208 | #if (CONFIG_CODEC == SWCODEC) |
213 | case WPS_TOKEN_CROSSFADE: | 209 | case WPS_TOKEN_CROSSFADE: |
214 | snprintf(buf, sizeof(buf), "crossfade"); | 210 | snprintf(buf, bufsize, "crossfade"); |
215 | break; | 211 | break; |
216 | 212 | ||
217 | case WPS_TOKEN_REPLAYGAIN: | 213 | case WPS_TOKEN_REPLAYGAIN: |
218 | snprintf(buf, sizeof(buf), "replaygain"); | 214 | snprintf(buf, bufsize, "replaygain"); |
219 | break; | 215 | break; |
220 | #endif | 216 | #endif |
221 | 217 | ||
222 | #ifdef HAVE_ALBUMART | 218 | #ifdef HAVE_ALBUMART |
223 | case WPS_TOKEN_ALBUMART_DISPLAY: | 219 | case WPS_TOKEN_ALBUMART_DISPLAY: |
224 | snprintf(buf, sizeof(buf), "album art display at x=%d, y=%d, " | 220 | snprintf(buf, bufsize, "album art display"); |
225 | "maxwidth=%d, maxheight=%d", data->albumart_x, | 221 | break; |
226 | data->albumart_y, data->albumart_max_width, | 222 | |
227 | data->albumart_max_height); | 223 | case WPS_TOKEN_ALBUMART_FOUND: |
228 | break; | 224 | snprintf(buf, bufsize, "%strack album art conditional", |
225 | next_str(next)); | ||
226 | break; | ||
229 | #endif | 227 | #endif |
230 | 228 | ||
231 | #ifdef HAVE_LCD_BITMAP | 229 | #ifdef HAVE_LCD_BITMAP |
232 | case WPS_TOKEN_IMAGE_BACKDROP: | 230 | case WPS_TOKEN_IMAGE_BACKDROP: |
233 | snprintf(buf, sizeof(buf), "backdrop image"); | 231 | snprintf(buf, bufsize, "backdrop image"); |
234 | break; | 232 | break; |
235 | 233 | ||
236 | case WPS_TOKEN_IMAGE_PROGRESS_BAR: | 234 | case WPS_TOKEN_IMAGE_PROGRESS_BAR: |
237 | snprintf(buf, sizeof(buf), "progressbar bitmap"); | 235 | snprintf(buf, bufsize, "progressbar bitmap"); |
238 | break; | 236 | break; |
239 | 237 | ||
240 | case WPS_TOKEN_PEAKMETER: | 238 | case WPS_TOKEN_PEAKMETER: |
241 | snprintf(buf, sizeof(buf), "peakmeter"); | 239 | snprintf(buf, bufsize, "peakmeter"); |
242 | break; | 240 | break; |
243 | #endif | 241 | #endif |
244 | 242 | ||
245 | case WPS_TOKEN_PROGRESSBAR: | 243 | case WPS_TOKEN_PROGRESSBAR: |
246 | snprintf(buf, sizeof(buf), "progressbar"); | 244 | snprintf(buf, bufsize, "progressbar"); |
247 | break; | 245 | break; |
248 | 246 | ||
249 | #ifdef HAVE_LCD_CHARCELLS | 247 | #ifdef HAVE_LCD_CHARCELLS |
250 | case WPS_TOKEN_PLAYER_PROGRESSBAR: | 248 | case WPS_TOKEN_PLAYER_PROGRESSBAR: |
251 | snprintf(buf, sizeof(buf), "full line progressbar"); | 249 | snprintf(buf, bufsize, "full line progressbar"); |
252 | break; | 250 | break; |
253 | #endif | 251 | #endif |
254 | 252 | ||
255 | case WPS_TOKEN_TRACK_TIME_ELAPSED: | 253 | case WPS_TOKEN_TRACK_TIME_ELAPSED: |
256 | snprintf(buf, sizeof(buf), "time elapsed in track"); | 254 | snprintf(buf, bufsize, "time elapsed in track"); |
257 | break; | 255 | break; |
258 | 256 | ||
259 | case WPS_TOKEN_TRACK_ELAPSED_PERCENT: | 257 | case WPS_TOKEN_TRACK_ELAPSED_PERCENT: |
260 | snprintf(buf, sizeof(buf), "played percentage of track"); | 258 | snprintf(buf, bufsize, "played percentage of track"); |
261 | break; | 259 | break; |
262 | 260 | ||
263 | case WPS_TOKEN_PLAYLIST_ENTRIES: | 261 | case WPS_TOKEN_PLAYLIST_ENTRIES: |
264 | snprintf(buf, sizeof(buf), "number of entries in playlist"); | 262 | snprintf(buf, bufsize, "number of entries in playlist"); |
265 | break; | 263 | break; |
266 | 264 | ||
267 | case WPS_TOKEN_PLAYLIST_NAME: | 265 | case WPS_TOKEN_PLAYLIST_NAME: |
268 | snprintf(buf, sizeof(buf), "playlist name"); | 266 | snprintf(buf, bufsize, "playlist name"); |
269 | break; | 267 | break; |
270 | 268 | ||
271 | case WPS_TOKEN_PLAYLIST_POSITION: | 269 | case WPS_TOKEN_PLAYLIST_POSITION: |
272 | snprintf(buf, sizeof(buf), "position in playlist"); | 270 | snprintf(buf, bufsize, "position in playlist"); |
273 | break; | 271 | break; |
274 | 272 | ||
275 | case WPS_TOKEN_TRACK_TIME_REMAINING: | 273 | case WPS_TOKEN_TRACK_TIME_REMAINING: |
276 | snprintf(buf, sizeof(buf), "time remaining in track"); | 274 | snprintf(buf, bufsize, "time remaining in track"); |
277 | break; | 275 | break; |
278 | 276 | ||
279 | case WPS_TOKEN_PLAYLIST_SHUFFLE: | 277 | case WPS_TOKEN_PLAYLIST_SHUFFLE: |
280 | snprintf(buf, sizeof(buf), "playlist shuffle mode"); | 278 | snprintf(buf, bufsize, "playlist shuffle mode"); |
281 | break; | 279 | break; |
282 | 280 | ||
283 | case WPS_TOKEN_TRACK_LENGTH: | 281 | case WPS_TOKEN_TRACK_LENGTH: |
284 | snprintf(buf, sizeof(buf), "track length"); | 282 | snprintf(buf, bufsize, "track length"); |
285 | break; | 283 | break; |
286 | 284 | ||
287 | case WPS_TOKEN_VOLUME: | 285 | case WPS_TOKEN_VOLUME: |
288 | snprintf(buf, sizeof(buf), "volume"); | 286 | snprintf(buf, bufsize, "volume"); |
289 | break; | 287 | break; |
290 | 288 | ||
291 | case WPS_TOKEN_METADATA_ARTIST: | 289 | case WPS_TOKEN_METADATA_ARTIST: |
292 | snprintf(buf, sizeof(buf), "%strack artist", | 290 | snprintf(buf, bufsize, "%strack artist", |
293 | next_str(next)); | 291 | next_str(next)); |
294 | break; | 292 | break; |
295 | 293 | ||
296 | case WPS_TOKEN_METADATA_COMPOSER: | 294 | case WPS_TOKEN_METADATA_COMPOSER: |
297 | snprintf(buf, sizeof(buf), "%strack composer", | 295 | snprintf(buf, bufsize, "%strack composer", |
298 | next_str(next)); | 296 | next_str(next)); |
299 | break; | 297 | break; |
300 | 298 | ||
301 | case WPS_TOKEN_METADATA_ALBUM: | 299 | case WPS_TOKEN_METADATA_ALBUM: |
302 | snprintf(buf, sizeof(buf), "%strack album", | 300 | snprintf(buf, bufsize, "%strack album", |
303 | next_str(next)); | 301 | next_str(next)); |
304 | break; | 302 | break; |
305 | 303 | ||
306 | case WPS_TOKEN_METADATA_GROUPING: | 304 | case WPS_TOKEN_METADATA_GROUPING: |
307 | snprintf(buf, sizeof(buf), "%strack grouping", | 305 | snprintf(buf, bufsize, "%strack grouping", |
308 | next_str(next)); | 306 | next_str(next)); |
309 | break; | 307 | break; |
310 | 308 | ||
311 | case WPS_TOKEN_METADATA_GENRE: | 309 | case WPS_TOKEN_METADATA_GENRE: |
312 | snprintf(buf, sizeof(buf), "%strack genre", | 310 | snprintf(buf, bufsize, "%strack genre", |
313 | next_str(next)); | 311 | next_str(next)); |
314 | break; | 312 | break; |
315 | 313 | ||
316 | case WPS_TOKEN_METADATA_DISC_NUMBER: | 314 | case WPS_TOKEN_METADATA_DISC_NUMBER: |
317 | snprintf(buf, sizeof(buf), "%strack disc", next_str(next)); | 315 | snprintf(buf, bufsize, "%strack disc", next_str(next)); |
318 | break; | 316 | break; |
319 | 317 | ||
320 | case WPS_TOKEN_METADATA_TRACK_NUMBER: | 318 | case WPS_TOKEN_METADATA_TRACK_NUMBER: |
321 | snprintf(buf, sizeof(buf), "%strack number", | 319 | snprintf(buf, bufsize, "%strack number", |
322 | next_str(next)); | 320 | next_str(next)); |
323 | break; | 321 | break; |
324 | 322 | ||
325 | case WPS_TOKEN_METADATA_TRACK_TITLE: | 323 | case WPS_TOKEN_METADATA_TRACK_TITLE: |
326 | snprintf(buf, sizeof(buf), "%strack title", | 324 | snprintf(buf, bufsize, "%strack title", |
327 | next_str(next)); | 325 | next_str(next)); |
328 | break; | 326 | break; |
329 | 327 | ||
330 | case WPS_TOKEN_METADATA_VERSION: | 328 | case WPS_TOKEN_METADATA_VERSION: |
331 | snprintf(buf, sizeof(buf), "%strack ID3 version", | 329 | snprintf(buf, bufsize, "%strack ID3 version", |
332 | next_str(next)); | 330 | next_str(next)); |
333 | break; | 331 | break; |
334 | 332 | ||
335 | case WPS_TOKEN_METADATA_YEAR: | 333 | case WPS_TOKEN_METADATA_ALBUM_ARTIST: |
336 | snprintf(buf, sizeof(buf), "%strack year", next_str(next)); | 334 | snprintf(buf, bufsize, "%strack album artist", |
337 | break; | 335 | next_str(next)); |
338 | 336 | break; | |
339 | case WPS_TOKEN_BATTERY_PERCENT: | 337 | |
340 | snprintf(buf, sizeof(buf), "battery percentage"); | 338 | case WPS_TOKEN_METADATA_COMMENT: |
341 | break; | 339 | snprintf(buf, bufsize, "%strack comment", |
342 | 340 | next_str(next)); | |
343 | case WPS_TOKEN_BATTERY_VOLTS: | 341 | break; |
344 | snprintf(buf, sizeof(buf), "battery voltage"); | 342 | |
345 | break; | 343 | case WPS_TOKEN_METADATA_YEAR: |
346 | 344 | snprintf(buf, bufsize, "%strack year", next_str(next)); | |
347 | case WPS_TOKEN_BATTERY_TIME: | 345 | break; |
348 | snprintf(buf, sizeof(buf), "battery time left"); | 346 | |
349 | break; | 347 | #ifdef HAVE_TAGCACHE |
350 | 348 | case WPS_TOKEN_DATABASE_PLAYCOUNT: | |
351 | case WPS_TOKEN_BATTERY_CHARGER_CONNECTED: | 349 | snprintf(buf, bufsize, "track playcount (database)"); |
352 | snprintf(buf, sizeof(buf), "battery charger connected"); | 350 | break; |
353 | break; | 351 | |
354 | 352 | case WPS_TOKEN_DATABASE_RATING: | |
355 | case WPS_TOKEN_BATTERY_CHARGING: | 353 | snprintf(buf, bufsize, "track rating (database)"); |
356 | snprintf(buf, sizeof(buf), "battery charging"); | 354 | break; |
357 | break; | 355 | |
358 | 356 | case WPS_TOKEN_DATABASE_AUTOSCORE: | |
359 | case WPS_TOKEN_FILE_BITRATE: | 357 | snprintf(buf, bufsize, "track autoscore (database)"); |
360 | snprintf(buf, sizeof(buf), "%sfile bitrate", next_str(next)); | 358 | break; |
361 | break; | 359 | #endif |
362 | |||
363 | case WPS_TOKEN_FILE_CODEC: | ||
364 | snprintf(buf, sizeof(buf), "%sfile codec", next_str(next)); | ||
365 | break; | ||
366 | |||
367 | case WPS_TOKEN_FILE_FREQUENCY: | ||
368 | snprintf(buf, sizeof(buf), "%sfile audio frequency in Hz", | ||
369 | next_str(next)); | ||
370 | break; | ||
371 | 360 | ||
372 | case WPS_TOKEN_FILE_FREQUENCY_KHZ: | 361 | case WPS_TOKEN_BATTERY_PERCENT: |
373 | snprintf(buf, sizeof(buf), "%sfile audio frequency in KHz", | 362 | snprintf(buf, bufsize, "battery percentage"); |
374 | next_str(next)); | 363 | break; |
375 | break; | 364 | |
365 | case WPS_TOKEN_BATTERY_VOLTS: | ||
366 | snprintf(buf, bufsize, "battery voltage"); | ||
367 | break; | ||
368 | |||
369 | case WPS_TOKEN_BATTERY_TIME: | ||
370 | snprintf(buf, bufsize, "battery time left"); | ||
371 | break; | ||
372 | |||
373 | case WPS_TOKEN_BATTERY_CHARGER_CONNECTED: | ||
374 | snprintf(buf, bufsize, "battery charger connected"); | ||
375 | break; | ||
376 | |||
377 | case WPS_TOKEN_BATTERY_CHARGING: | ||
378 | snprintf(buf, bufsize, "battery charging"); | ||
379 | break; | ||
380 | |||
381 | case WPS_TOKEN_BATTERY_SLEEPTIME: | ||
382 | snprintf(buf, bufsize, "sleep timer"); | ||
383 | break; | ||
384 | |||
385 | case WPS_TOKEN_FILE_BITRATE: | ||
386 | snprintf(buf, bufsize, "%sfile bitrate", next_str(next)); | ||
387 | break; | ||
388 | |||
389 | case WPS_TOKEN_FILE_CODEC: | ||
390 | snprintf(buf, bufsize, "%sfile codec", next_str(next)); | ||
391 | break; | ||
392 | |||
393 | case WPS_TOKEN_FILE_FREQUENCY: | ||
394 | snprintf(buf, bufsize, "%sfile audio frequency in Hz", | ||
395 | next_str(next)); | ||
396 | break; | ||
397 | |||
398 | case WPS_TOKEN_FILE_FREQUENCY_KHZ: | ||
399 | snprintf(buf, bufsize, "%sfile audio frequency in KHz", | ||
400 | next_str(next)); | ||
401 | break; | ||
402 | |||
403 | case WPS_TOKEN_FILE_NAME: | ||
404 | snprintf(buf, bufsize, "%sfile name", next_str(next)); | ||
405 | break; | ||
406 | |||
407 | case WPS_TOKEN_FILE_NAME_WITH_EXTENSION: | ||
408 | snprintf(buf, bufsize, "%sfile name with extension", | ||
409 | next_str(next)); | ||
410 | break; | ||
411 | |||
412 | case WPS_TOKEN_FILE_PATH: | ||
413 | snprintf(buf, bufsize, "%sfile path", next_str(next)); | ||
414 | break; | ||
415 | |||
416 | case WPS_TOKEN_FILE_SIZE: | ||
417 | snprintf(buf, bufsize, "%sfile size", next_str(next)); | ||
418 | break; | ||
419 | |||
420 | case WPS_TOKEN_FILE_VBR: | ||
421 | snprintf(buf, bufsize, "%sfile is vbr", next_str(next)); | ||
422 | break; | ||
423 | |||
424 | case WPS_TOKEN_FILE_DIRECTORY: | ||
425 | snprintf(buf, bufsize, "%sfile directory, level: %d", | ||
426 | next_str(next), token->value.i); | ||
427 | break; | ||
428 | |||
429 | case WPS_TOKEN_SOUND_PITCH: | ||
430 | snprintf(buf, bufsize, "pitch value"); | ||
431 | break; | ||
432 | |||
433 | default: | ||
434 | snprintf(buf, bufsize, "FIXME (code: %d)", | ||
435 | token->type); | ||
436 | break; | ||
437 | } | ||
376 | 438 | ||
377 | case WPS_TOKEN_FILE_NAME: | 439 | return buf; |
378 | snprintf(buf, sizeof(buf), "%sfile name", next_str(next)); | 440 | } |
379 | break; | ||
380 | 441 | ||
381 | case WPS_TOKEN_FILE_NAME_WITH_EXTENSION: | 442 | static void dump_wps_tokens(struct wps_data *data) |
382 | snprintf(buf, sizeof(buf), "%sfile name with extension", | 443 | { |
383 | next_str(next)); | 444 | struct wps_token *token; |
384 | break; | 445 | int i, j; |
446 | int indent = 0; | ||
447 | char buf[64]; | ||
448 | int num_string_tokens = 0; | ||
385 | 449 | ||
386 | case WPS_TOKEN_FILE_PATH: | 450 | /* Dump parsed WPS */ |
387 | snprintf(buf, sizeof(buf), "%sfile path", next_str(next)); | 451 | for (i = 0, token = data->tokens; i < data->num_tokens; i++, token++) |
388 | break; | 452 | { |
453 | get_token_desc(token, data, buf, sizeof(buf)); | ||
389 | 454 | ||
390 | case WPS_TOKEN_FILE_SIZE: | 455 | switch(token->type) |
391 | snprintf(buf, sizeof(buf), "%sfile size", next_str(next)); | 456 | { |
457 | case WPS_TOKEN_STRING: | ||
458 | num_string_tokens++; | ||
392 | break; | 459 | break; |
393 | 460 | ||
394 | case WPS_TOKEN_FILE_VBR: | 461 | case WPS_TOKEN_CONDITIONAL_START: |
395 | snprintf(buf, sizeof(buf), "%sfile is vbr", next_str(next)); | 462 | indent++; |
396 | break; | 463 | break; |
397 | 464 | ||
398 | case WPS_TOKEN_FILE_DIRECTORY: | 465 | case WPS_TOKEN_CONDITIONAL_END: |
399 | snprintf(buf, sizeof(buf), "%sfile directory, level: %d", | 466 | indent--; |
400 | next_str(next), token->value.i); | ||
401 | break; | 467 | break; |
402 | 468 | ||
403 | default: | 469 | default: |
404 | snprintf(buf, sizeof(buf), "FIXME (code: %d)", | ||
405 | token->type); | ||
406 | break; | 470 | break; |
407 | } | 471 | } |
408 | 472 | ||
@@ -528,6 +592,8 @@ void print_debug_info(struct wps_data *data, int fail, int line) | |||
528 | 592 | ||
529 | if (fail) | 593 | if (fail) |
530 | { | 594 | { |
595 | char buf[64]; | ||
596 | |||
531 | DEBUGF("Failed parsing on line %d : ", line); | 597 | DEBUGF("Failed parsing on line %d : ", line); |
532 | switch (fail) | 598 | switch (fail) |
533 | { | 599 | { |
@@ -536,11 +602,27 @@ void print_debug_info(struct wps_data *data, int fail, int line) | |||
536 | break; | 602 | break; |
537 | 603 | ||
538 | case PARSE_FAIL_INVALID_CHAR: | 604 | case PARSE_FAIL_INVALID_CHAR: |
539 | DEBUGF("Invalid conditional char (not in an open conditional)"); | 605 | DEBUGF("unexpected conditional char after token %d: \"%s\"", |
606 | data->num_tokens-1, | ||
607 | get_token_desc(&data->tokens[data->num_tokens-1], data, | ||
608 | buf, sizeof(buf)) | ||
609 | ); | ||
540 | break; | 610 | break; |
541 | 611 | ||
542 | case PARSE_FAIL_COND_SYNTAX_ERROR: | 612 | case PARSE_FAIL_COND_SYNTAX_ERROR: |
543 | DEBUGF("Conditional syntax error"); | 613 | DEBUGF("Conditional syntax error after token %d: \"%s\"", |
614 | data->num_tokens-1, | ||
615 | get_token_desc(&data->tokens[data->num_tokens-1], data, | ||
616 | buf, sizeof(buf)) | ||
617 | ); | ||
618 | break; | ||
619 | |||
620 | case PARSE_FAIL_COND_INVALID_PARAM: | ||
621 | DEBUGF("Invalid parameter list for token %d: \"%s\"", | ||
622 | data->num_tokens, | ||
623 | get_token_desc(&data->tokens[data->num_tokens], data, | ||
624 | buf, sizeof(buf)) | ||
625 | ); | ||
544 | break; | 626 | break; |
545 | } | 627 | } |
546 | DEBUGF("\n"); | 628 | DEBUGF("\n"); |
diff --git a/apps/gui/wps_parser.c b/apps/gui/wps_parser.c index 907a8a3278..07805f20c7 100644 --- a/apps/gui/wps_parser.c +++ b/apps/gui/wps_parser.c | |||
@@ -42,9 +42,12 @@ | |||
42 | #define WPS_DEFAULTCFG WPS_DIR "/rockbox_default.wps" | 42 | #define WPS_DEFAULTCFG WPS_DIR "/rockbox_default.wps" |
43 | #define RWPS_DEFAULTCFG WPS_DIR "/rockbox_default.rwps" | 43 | #define RWPS_DEFAULTCFG WPS_DIR "/rockbox_default.rwps" |
44 | 44 | ||
45 | #define PARSE_FAIL_UNCLOSED_COND 1 | 45 | #define WPS_ERROR_INVALID_PARAM -1 |
46 | #define PARSE_FAIL_INVALID_CHAR 2 | 46 | |
47 | #define PARSE_FAIL_COND_SYNTAX_ERROR 3 | 47 | #define PARSE_FAIL_UNCLOSED_COND 1 |
48 | #define PARSE_FAIL_INVALID_CHAR 2 | ||
49 | #define PARSE_FAIL_COND_SYNTAX_ERROR 3 | ||
50 | #define PARSE_FAIL_COND_INVALID_PARAM 4 | ||
48 | 51 | ||
49 | /* level of current conditional. | 52 | /* level of current conditional. |
50 | -1 means we're not in a conditional. */ | 53 | -1 means we're not in a conditional. */ |
@@ -115,7 +118,7 @@ static int parse_dir_level(const char *wps_bufptr, | |||
115 | struct wps_token *token, struct wps_data *wps_data); | 118 | struct wps_token *token, struct wps_data *wps_data); |
116 | 119 | ||
117 | #ifdef HAVE_LCD_BITMAP | 120 | #ifdef HAVE_LCD_BITMAP |
118 | static int parse_scrollmargin(const char *wps_bufptr, | 121 | static int parse_leftmargin(const char *wps_bufptr, |
119 | struct wps_token *token, struct wps_data *wps_data); | 122 | struct wps_token *token, struct wps_data *wps_data); |
120 | static int parse_image_special(const char *wps_bufptr, | 123 | static int parse_image_special(const char *wps_bufptr, |
121 | struct wps_token *token, struct wps_data *wps_data); | 124 | struct wps_token *token, struct wps_data *wps_data); |
@@ -253,7 +256,7 @@ static const struct wps_tag all_tags[] = { | |||
253 | { WPS_TOKEN_PLAYBACK_STATUS, "mp", WPS_REFRESH_DYNAMIC, NULL }, | 256 | { WPS_TOKEN_PLAYBACK_STATUS, "mp", WPS_REFRESH_DYNAMIC, NULL }, |
254 | 257 | ||
255 | #ifdef HAVE_LCD_BITMAP | 258 | #ifdef HAVE_LCD_BITMAP |
256 | { WPS_TOKEN_LEFTMARGIN, "m", 0, parse_scrollmargin }, | 259 | { WPS_TOKEN_LEFTMARGIN, "m", 0, parse_leftmargin }, |
257 | #endif | 260 | #endif |
258 | 261 | ||
259 | #ifdef HAVE_LCD_BITMAP | 262 | #ifdef HAVE_LCD_BITMAP |
@@ -277,9 +280,12 @@ static const struct wps_tag all_tags[] = { | |||
277 | { WPS_TOKEN_PLAYLIST_NAME, "pn", WPS_REFRESH_STATIC, NULL }, | 280 | { WPS_TOKEN_PLAYLIST_NAME, "pn", WPS_REFRESH_STATIC, NULL }, |
278 | { WPS_TOKEN_PLAYLIST_SHUFFLE, "ps", WPS_REFRESH_DYNAMIC, NULL }, | 281 | { WPS_TOKEN_PLAYLIST_SHUFFLE, "ps", WPS_REFRESH_DYNAMIC, NULL }, |
279 | 282 | ||
283 | #ifdef HAVE_TAGCACHE | ||
280 | { WPS_TOKEN_DATABASE_PLAYCOUNT, "rp", WPS_REFRESH_DYNAMIC, NULL }, | 284 | { WPS_TOKEN_DATABASE_PLAYCOUNT, "rp", WPS_REFRESH_DYNAMIC, NULL }, |
281 | { WPS_TOKEN_DATABASE_RATING, "rr", WPS_REFRESH_DYNAMIC, NULL }, | 285 | { WPS_TOKEN_DATABASE_RATING, "rr", WPS_REFRESH_DYNAMIC, NULL }, |
282 | { WPS_TOKEN_DATABASE_AUTOSCORE, "ra", WPS_REFRESH_DYNAMIC, NULL }, | 286 | { WPS_TOKEN_DATABASE_AUTOSCORE, "ra", WPS_REFRESH_DYNAMIC, NULL }, |
287 | #endif | ||
288 | |||
283 | #if CONFIG_CODEC == SWCODEC | 289 | #if CONFIG_CODEC == SWCODEC |
284 | { WPS_TOKEN_REPLAYGAIN, "rg", WPS_REFRESH_STATIC, NULL }, | 290 | { WPS_TOKEN_REPLAYGAIN, "rg", WPS_REFRESH_STATIC, NULL }, |
285 | { WPS_TOKEN_CROSSFADE, "xf", WPS_REFRESH_DYNAMIC, NULL }, | 291 | { WPS_TOKEN_CROSSFADE, "xf", WPS_REFRESH_DYNAMIC, NULL }, |
@@ -425,8 +431,7 @@ static int parse_image_display(const char *wps_bufptr, | |||
425 | if (n == -1) | 431 | if (n == -1) |
426 | { | 432 | { |
427 | /* invalid picture display tag */ | 433 | /* invalid picture display tag */ |
428 | token->type = WPS_TOKEN_UNKNOWN; | 434 | return WPS_ERROR_INVALID_PARAM; |
429 | return 0; | ||
430 | } | 435 | } |
431 | 436 | ||
432 | token->value.i = n; | 437 | token->value.i = n; |
@@ -444,15 +449,17 @@ static int parse_image_load(const char *wps_bufptr, | |||
444 | { | 449 | { |
445 | int n; | 450 | int n; |
446 | const char *ptr = wps_bufptr; | 451 | const char *ptr = wps_bufptr; |
447 | char *pos = NULL; | 452 | const char *pos = NULL; |
453 | const char *newline; | ||
448 | 454 | ||
449 | /* format: %x|n|filename.bmp|x|y| | 455 | /* format: %x|n|filename.bmp|x|y| |
450 | or %xl|n|filename.bmp|x|y| */ | 456 | or %xl|n|filename.bmp|x|y| */ |
451 | 457 | ||
452 | ptr = strchr(ptr, '|') + 1; | 458 | ptr = strchr(ptr, '|') + 1; |
453 | pos = strchr(ptr, '|'); | 459 | pos = strchr(ptr, '|'); |
460 | newline = strchr(ptr, '\n'); | ||
454 | 461 | ||
455 | if (!pos) | 462 | if (!pos || pos > newline) |
456 | return 0; | 463 | return 0; |
457 | 464 | ||
458 | /* get the image ID */ | 465 | /* get the image ID */ |
@@ -461,8 +468,8 @@ static int parse_image_load(const char *wps_bufptr, | |||
461 | /* check the image number and load state */ | 468 | /* check the image number and load state */ |
462 | if(n < 0 || n >= MAX_IMAGES || wps_data->img[n].loaded) | 469 | if(n < 0 || n >= MAX_IMAGES || wps_data->img[n].loaded) |
463 | { | 470 | { |
464 | /* Skip the rest of the line */ | 471 | /* Invalid image ID */ |
465 | return 0; | 472 | return WPS_ERROR_INVALID_PARAM; |
466 | } | 473 | } |
467 | 474 | ||
468 | ptr = pos + 1; | 475 | ptr = pos + 1; |
@@ -475,23 +482,23 @@ static int parse_image_load(const char *wps_bufptr, | |||
475 | 482 | ||
476 | /* get x-position */ | 483 | /* get x-position */ |
477 | pos = strchr(ptr, '|'); | 484 | pos = strchr(ptr, '|'); |
478 | if (pos) | 485 | if (pos && pos < newline) |
479 | wps_data->img[n].x = atoi(ptr); | 486 | wps_data->img[n].x = atoi(ptr); |
480 | else | 487 | else |
481 | { | 488 | { |
482 | /* weird syntax, bail out */ | 489 | /* weird syntax, bail out */ |
483 | return 0; | 490 | return WPS_ERROR_INVALID_PARAM; |
484 | } | 491 | } |
485 | 492 | ||
486 | /* get y-position */ | 493 | /* get y-position */ |
487 | ptr = pos + 1; | 494 | ptr = pos + 1; |
488 | pos = strchr(ptr, '|'); | 495 | pos = strchr(ptr, '|'); |
489 | if (pos) | 496 | if (pos && pos < newline) |
490 | wps_data->img[n].y = atoi(ptr); | 497 | wps_data->img[n].y = atoi(ptr); |
491 | else | 498 | else |
492 | { | 499 | { |
493 | /* weird syntax, bail out */ | 500 | /* weird syntax, bail out */ |
494 | return 0; | 501 | return WPS_ERROR_INVALID_PARAM; |
495 | } | 502 | } |
496 | 503 | ||
497 | if (token->type == WPS_TOKEN_IMAGE_DISPLAY) | 504 | if (token->type == WPS_TOKEN_IMAGE_DISPLAY) |
@@ -505,6 +512,16 @@ static int parse_image_special(const char *wps_bufptr, | |||
505 | struct wps_token *token, | 512 | struct wps_token *token, |
506 | struct wps_data *wps_data) | 513 | struct wps_data *wps_data) |
507 | { | 514 | { |
515 | (void)wps_data; /* kill warning */ | ||
516 | const char *pos = NULL; | ||
517 | const char *newline; | ||
518 | |||
519 | pos = strchr(wps_bufptr + 1, '|'); | ||
520 | newline = strchr(wps_bufptr, '\n'); | ||
521 | |||
522 | if (pos > newline) | ||
523 | return WPS_ERROR_INVALID_PARAM; | ||
524 | |||
508 | if (token->type == WPS_TOKEN_IMAGE_PROGRESS_BAR) | 525 | if (token->type == WPS_TOKEN_IMAGE_PROGRESS_BAR) |
509 | { | 526 | { |
510 | /* format: %P|filename.bmp| */ | 527 | /* format: %P|filename.bmp| */ |
@@ -518,8 +535,6 @@ static int parse_image_special(const char *wps_bufptr, | |||
518 | } | 535 | } |
519 | #endif | 536 | #endif |
520 | 537 | ||
521 | (void)wps_data; /* to avoid a warning */ | ||
522 | |||
523 | /* Skip the rest of the line */ | 538 | /* Skip the rest of the line */ |
524 | return skip_end_of_line(wps_bufptr); | 539 | return skip_end_of_line(wps_bufptr); |
525 | } | 540 | } |
@@ -632,7 +647,7 @@ static int parse_albumart_load(const char *wps_bufptr, | |||
632 | struct wps_token *token, | 647 | struct wps_token *token, |
633 | struct wps_data *wps_data) | 648 | struct wps_data *wps_data) |
634 | { | 649 | { |
635 | const char* _pos; | 650 | const char *_pos, *newline; |
636 | bool parsing; | 651 | bool parsing; |
637 | const short xalign_mask = WPS_ALBUMART_ALIGN_LEFT | | 652 | const short xalign_mask = WPS_ALBUMART_ALIGN_LEFT | |
638 | WPS_ALBUMART_ALIGN_CENTER | | 653 | WPS_ALBUMART_ALIGN_CENTER | |
@@ -652,25 +667,27 @@ static int parse_albumart_load(const char *wps_bufptr, | |||
652 | 667 | ||
653 | /* format: %Cl|x|y|[[l|c|r][d|i|s]mwidth]|[[t|c|b][d|i|s]mheight]| */ | 668 | /* format: %Cl|x|y|[[l|c|r][d|i|s]mwidth]|[[t|c|b][d|i|s]mheight]| */ |
654 | 669 | ||
670 | newline = strchr(wps_bufptr, '\n'); | ||
671 | |||
655 | /* initial validation and parsing of x and y components */ | 672 | /* initial validation and parsing of x and y components */ |
656 | if (*wps_bufptr != '|') | 673 | if (*wps_bufptr != '|') |
657 | return 0; /* malformed token: e.g. %Cl7 */ | 674 | return WPS_ERROR_INVALID_PARAM; /* malformed token: e.g. %Cl7 */ |
658 | 675 | ||
659 | _pos = wps_bufptr + 1; | 676 | _pos = wps_bufptr + 1; |
660 | if (!isdigit(*_pos)) | 677 | if (!isdigit(*_pos)) |
661 | return 0; /* malformed token: e.g. %Cl|@ */ | 678 | return WPS_ERROR_INVALID_PARAM; /* malformed token: e.g. %Cl|@ */ |
662 | wps_data->albumart_x = atoi(_pos); | 679 | wps_data->albumart_x = atoi(_pos); |
663 | 680 | ||
664 | _pos = strchr(_pos, '|'); | 681 | _pos = strchr(_pos, '|'); |
665 | if (!_pos || !isdigit(*(++_pos))) | 682 | if (!_pos || _pos > newline || !isdigit(*(++_pos))) |
666 | return 0; /* malformed token: e.g. %Cl|7\n or %Cl|7|@ */ | 683 | return WPS_ERROR_INVALID_PARAM; /* malformed token: e.g. %Cl|7\n or %Cl|7|@ */ |
667 | 684 | ||
668 | wps_data->albumart_y = atoi(_pos); | 685 | wps_data->albumart_y = atoi(_pos); |
669 | 686 | ||
670 | _pos = strchr(_pos, '|'); | 687 | _pos = strchr(_pos, '|'); |
671 | if (!_pos) | 688 | if (!_pos || _pos > newline) |
672 | return 0; /* malformed token: no | after y coordinate | 689 | return WPS_ERROR_INVALID_PARAM; /* malformed token: no | after y coordinate |
673 | e.g. %Cl|7|59\n */ | 690 | e.g. %Cl|7|59\n */ |
674 | 691 | ||
675 | /* parsing width field */ | 692 | /* parsing width field */ |
676 | parsing = true; | 693 | parsing = true; |
@@ -721,13 +738,15 @@ static int parse_albumart_load(const char *wps_bufptr, | |||
721 | /* extract max width data */ | 738 | /* extract max width data */ |
722 | if (*_pos != '|') | 739 | if (*_pos != '|') |
723 | { | 740 | { |
724 | if (!isdigit(*_pos)) | 741 | if (!isdigit(*_pos)) /* malformed token: e.g. %Cl|7|59|# */ |
725 | return 0; /* malformed token: e.g. %Cl|7|59|# */ | 742 | return WPS_ERROR_INVALID_PARAM; |
743 | |||
726 | wps_data->albumart_max_width = atoi(_pos); | 744 | wps_data->albumart_max_width = atoi(_pos); |
745 | |||
727 | _pos = strchr(_pos, '|'); | 746 | _pos = strchr(_pos, '|'); |
728 | if (!_pos) | 747 | if (!_pos || _pos > newline) |
729 | return 0; /* malformed token: no | after width field | 748 | return WPS_ERROR_INVALID_PARAM; /* malformed token: no | after width field |
730 | e.g. %Cl|7|59|200\n */ | 749 | e.g. %Cl|7|59|200\n */ |
731 | } | 750 | } |
732 | 751 | ||
733 | /* parsing height field */ | 752 | /* parsing height field */ |
@@ -780,12 +799,14 @@ static int parse_albumart_load(const char *wps_bufptr, | |||
780 | if (*_pos != '|') | 799 | if (*_pos != '|') |
781 | { | 800 | { |
782 | if (!isdigit(*_pos)) | 801 | if (!isdigit(*_pos)) |
783 | return 0; /* malformed token e.g. %Cl|7|59|200|@ */ | 802 | return WPS_ERROR_INVALID_PARAM; /* malformed token e.g. %Cl|7|59|200|@ */ |
803 | |||
784 | wps_data->albumart_max_height = atoi(_pos); | 804 | wps_data->albumart_max_height = atoi(_pos); |
805 | |||
785 | _pos = strchr(_pos, '|'); | 806 | _pos = strchr(_pos, '|'); |
786 | if (!_pos) | 807 | if (!_pos || _pos > newline) |
787 | return 0; /* malformed token: no closing | | 808 | return WPS_ERROR_INVALID_PARAM; /* malformed token: no closing | |
788 | e.g. %Cl|7|59|200|200\n */ | 809 | e.g. %Cl|7|59|200|200\n */ |
789 | } | 810 | } |
790 | 811 | ||
791 | /* if we got here, we parsed everything ok .. ! */ | 812 | /* if we got here, we parsed everything ok .. ! */ |
@@ -841,29 +862,29 @@ static int parse_albumart_conditional(const char *wps_bufptr, | |||
841 | #endif /* HAVE_ALBUMART */ | 862 | #endif /* HAVE_ALBUMART */ |
842 | 863 | ||
843 | #ifdef HAVE_LCD_BITMAP | 864 | #ifdef HAVE_LCD_BITMAP |
844 | static int parse_scrollmargin(const char *wps_bufptr, struct wps_token *token, | 865 | static int parse_leftmargin(const char *wps_bufptr, struct wps_token *token, |
845 | struct wps_data *wps_data) | 866 | struct wps_data *wps_data) |
846 | { | 867 | { |
847 | const char* p; | 868 | const char* p; |
848 | const char* pend; | 869 | const char* pend; |
870 | const char *newline; | ||
849 | 871 | ||
850 | (void)wps_data; /* Kill the warning */ | 872 | (void)wps_data; /* Kill the warning */ |
851 | 873 | ||
852 | /* valid tag looks like %m or %m|12| */ | 874 | /* valid tag looks like %m|12| */ |
853 | if(*wps_bufptr == '|') | 875 | if(*wps_bufptr == '|') |
854 | { | 876 | { |
855 | p = wps_bufptr + 1; | 877 | p = wps_bufptr + 1; |
856 | 878 | newline = strchr(wps_bufptr, '\n'); | |
857 | if(isdigit(*p) && (pend = strchr(p, '|'))) | 879 | if(isdigit(*p) && (pend = strchr(p, '|')) && pend < newline) |
858 | { | 880 | { |
859 | token->value.i = atoi(p); | 881 | token->value.i = atoi(p); |
860 | return(pend - wps_bufptr + 1); | 882 | return pend - wps_bufptr + 1; |
861 | } | 883 | } |
862 | } else { | ||
863 | token->value.i = 0; | ||
864 | } | 884 | } |
865 | 885 | ||
866 | return(0); | 886 | /* invalid tag syntax */ |
887 | return WPS_ERROR_INVALID_PARAM; | ||
867 | } | 888 | } |
868 | #endif | 889 | #endif |
869 | 890 | ||
@@ -871,7 +892,7 @@ static int parse_scrollmargin(const char *wps_bufptr, struct wps_token *token, | |||
871 | /* Parse a generic token from the given string. Return the length read */ | 892 | /* Parse a generic token from the given string. Return the length read */ |
872 | static int parse_token(const char *wps_bufptr, struct wps_data *wps_data) | 893 | static int parse_token(const char *wps_bufptr, struct wps_data *wps_data) |
873 | { | 894 | { |
874 | int skip = 0, taglen = 0; | 895 | int skip = 0, taglen = 0, ret; |
875 | struct wps_token *token = wps_data->tokens + wps_data->num_tokens; | 896 | struct wps_token *token = wps_data->tokens + wps_data->num_tokens; |
876 | const struct wps_tag *tag; | 897 | const struct wps_tag *tag; |
877 | 898 | ||
@@ -898,7 +919,9 @@ static int parse_token(const char *wps_bufptr, struct wps_data *wps_data) | |||
898 | condindex[level] = wps_data->num_tokens; | 919 | condindex[level] = wps_data->num_tokens; |
899 | numoptions[level] = 1; | 920 | numoptions[level] = 1; |
900 | wps_data->num_tokens++; | 921 | wps_data->num_tokens++; |
901 | taglen = 1 + parse_token(wps_bufptr + 1, wps_data); | 922 | ret = parse_token(wps_bufptr + 1, wps_data); |
923 | if (ret < 0) return ret; | ||
924 | taglen = 1 + ret; | ||
902 | break; | 925 | break; |
903 | 926 | ||
904 | default: | 927 | default: |
@@ -914,7 +937,11 @@ static int parse_token(const char *wps_bufptr, struct wps_data *wps_data) | |||
914 | 937 | ||
915 | /* if the tag has a special parsing function, we call it */ | 938 | /* if the tag has a special parsing function, we call it */ |
916 | if (tag->parse_func) | 939 | if (tag->parse_func) |
917 | skip += tag->parse_func(wps_bufptr + taglen, token, wps_data); | 940 | { |
941 | ret = tag->parse_func(wps_bufptr + taglen, token, wps_data); | ||
942 | if (ret < 0) return ret; | ||
943 | skip += ret; | ||
944 | } | ||
918 | 945 | ||
919 | /* Some tags we don't want to save as tokens */ | 946 | /* Some tags we don't want to save as tokens */ |
920 | if (tag->type == WPS_NO_TOKEN) | 947 | if (tag->type == WPS_NO_TOKEN) |
@@ -945,6 +972,7 @@ static bool wps_parse(struct wps_data *data, const char *wps_bufptr) | |||
945 | char *stringbuf = data->string_buffer; | 972 | char *stringbuf = data->string_buffer; |
946 | int stringbuf_used = 0; | 973 | int stringbuf_used = 0; |
947 | int fail = 0; | 974 | int fail = 0; |
975 | int ret; | ||
948 | line = 1; | 976 | line = 1; |
949 | level = -1; | 977 | level = -1; |
950 | 978 | ||
@@ -956,7 +984,12 @@ static bool wps_parse(struct wps_data *data, const char *wps_bufptr) | |||
956 | 984 | ||
957 | /* Regular tag */ | 985 | /* Regular tag */ |
958 | case '%': | 986 | case '%': |
959 | wps_bufptr += parse_token(wps_bufptr, data); | 987 | if ((ret = parse_token(wps_bufptr, data)) < 0) |
988 | { | ||
989 | fail = PARSE_FAIL_COND_INVALID_PARAM; | ||
990 | break; | ||
991 | } | ||
992 | wps_bufptr += ret; | ||
960 | break; | 993 | break; |
961 | 994 | ||
962 | /* Alternating sublines separator */ | 995 | /* Alternating sublines separator */ |