trunk/src/emu/webengine.c
| r25397 | r25398 | |
| 76 | 76 | mg_get_var(qs, strlen(qs == NULL ? "" : qs), name, dst, dst_len); |
| 77 | 77 | } |
| 78 | 78 | |
| 79 | char* websanitize_statefilename ( char* unsanitized ) |
| 80 | { |
| 81 | // It's important that we remove any dangerous characters from any filename |
| 82 | // we receive from a web client. This can be a serious security hole. |
| 83 | // As MAME/MESS policy is lowercase filenames, also lowercase it. |
| 84 | |
| 85 | char* sanitized = new char[64]; |
| 86 | int insertpoint =0; |
| 87 | char charcompare; |
| 88 | |
| 89 | while (*unsanitized != 0) |
| 90 | { |
| 91 | charcompare = *unsanitized; |
| 92 | // ASCII 48-57 are 0-9 |
| 93 | // ASCII 97-122 are lowercase A-Z |
| 94 | |
| 95 | if ((charcompare >= 48 && charcompare <= 57) || (charcompare >= 97 && charcompare <= 122)) |
| 96 | { |
| 97 | sanitized[insertpoint] = charcompare; |
| 98 | insertpoint++; |
| 99 | sanitized[insertpoint] = '\0'; // Make sure we're null-terminated. |
| 100 | } |
| 101 | // ASCII 65-90 are uppercase A-Z. These need to be lowercased. |
| 102 | if (charcompare >= 65 && charcompare <= 90) |
| 103 | { |
| 104 | sanitized[insertpoint] = tolower(charcompare); // Lowercase it |
| 105 | insertpoint++; |
| 106 | sanitized[insertpoint] = '\0'; // Make sure we're null-terminated. |
| 107 | } |
| 108 | unsanitized++; |
| 109 | } |
| 110 | return (sanitized); |
| 111 | } |
| 112 | |
| 79 | 113 | int web_engine::json_game_handler(struct mg_connection *conn) |
| 80 | 114 | { |
| 81 | 115 | Json::Value data; |
| r25397 | r25398 | |
| 189 | 223 | else |
| 190 | 224 | m_machine->pause(); |
| 191 | 225 | } |
| 226 | else if(!strcmp(cmd_name,"savestate")) |
| 227 | { |
| 228 | char cmd_val[64]; |
| 229 | get_qsvar(request_info, "val", cmd_val, sizeof(cmd_val)); |
| 230 | char *filename = websanitize_statefilename(cmd_val); |
| 231 | m_machine->schedule_save(filename); |
| 232 | } |
| 233 | else if(!strcmp(cmd_name,"loadstate")) |
| 234 | { |
| 235 | char cmd_val[64]; |
| 236 | get_qsvar(request_info, "val", cmd_val, sizeof(cmd_val)); |
| 237 | char *filename = cmd_val; |
| 238 | m_machine->schedule_load(filename); |
| 239 | } |
| 240 | else if(!strcmp(cmd_name,"loadauto")) |
| 241 | { |
| 242 | // This is here to just load the autosave and only the autosave. |
| 243 | m_machine->schedule_load("auto"); |
| 244 | } |
| 192 | 245 | |
| 193 | 246 | // Send HTTP reply to the client |
| 194 | 247 | mg_printf(conn, |
trunk/web/savestate.html
| r0 | r25398 | |
| 1 | Select position to save to |
| 2 | <!-- Yes, it's a little ugly. I could redo this more cleanly with a little javascript, but not right now. --> |
| 3 | <div data-role="controlgroup" data-type="horizontal"> |
| 4 | <a href="javascript:loadContent('commands');" data-role="button">Cancel</a> |
| 5 | <a href="javascript:executeCommands('savestate&val=auto');" data-role="button">Autosave Slot</a> |
| 6 | <a href="javascript:executeCommands('savestate&val=0');" data-role="button">0</a> |
| 7 | <a href="javascript:executeCommands('savestate&val=1');" data-role="button">1</a> |
| 8 | <a href="javascript:executeCommands('savestate&val=2');" data-role="button">2</a> |
| 9 | <a href="javascript:executeCommands('savestate&val=3');" data-role="button">3</a> |
| 10 | <a href="javascript:executeCommands('savestate&val=4');" data-role="button">4</a> |
| 11 | <a href="javascript:executeCommands('savestate&val=5');" data-role="button">5</a> |
| 12 | <a href="javascript:executeCommands('savestate&val=6');" data-role="button">6</a> |
| 13 | <a href="javascript:executeCommands('savestate&val=7');" data-role="button">7</a> |
| 14 | <a href="javascript:executeCommands('savestate&val=8');" data-role="button">8</a> |
| 15 | <a href="javascript:executeCommands('savestate&val=9');" data-role="button">9</a> |
| 16 | <a href="javascript:executeCommands('savestate&val=a');" data-role="button">A</a> |
| 17 | <a href="javascript:executeCommands('savestate&val=b');" data-role="button">B</a> |
| 18 | <a href="javascript:executeCommands('savestate&val=c');" data-role="button">C</a> |
| 19 | <a href="javascript:executeCommands('savestate&val=d');" data-role="button">D</a> |
| 20 | <a href="javascript:executeCommands('savestate&val=e');" data-role="button">E</a> |
| 21 | <a href="javascript:executeCommands('savestate&val=f');" data-role="button">F</a> |
| 22 | <a href="javascript:executeCommands('savestate&val=g');" data-role="button">G</a> |
| 23 | <a href="javascript:executeCommands('savestate&val=h');" data-role="button">H</a> |
| 24 | <a href="javascript:executeCommands('savestate&val=i');" data-role="button">I</a> |
| 25 | <a href="javascript:executeCommands('savestate&val=j');" data-role="button">J</a> |
| 26 | <a href="javascript:executeCommands('savestate&val=k');" data-role="button">K</a> |
| 27 | <a href="javascript:executeCommands('savestate&val=l');" data-role="button">L</a> |
| 28 | <a href="javascript:executeCommands('savestate&val=m');" data-role="button">M</a> |
| 29 | <a href="javascript:executeCommands('savestate&val=n');" data-role="button">N</a> |
| 30 | <a href="javascript:executeCommands('savestate&val=o');" data-role="button">O</a> |
| 31 | <a href="javascript:executeCommands('savestate&val=p');" data-role="button">P</a> |
| 32 | <a href="javascript:executeCommands('savestate&val=q');" data-role="button">Q</a> |
| 33 | <a href="javascript:executeCommands('savestate&val=r');" data-role="button">R</a> |
| 34 | <a href="javascript:executeCommands('savestate&val=s');" data-role="button">S</a> |
| 35 | <a href="javascript:executeCommands('savestate&val=t');" data-role="button">T</a> |
| 36 | <a href="javascript:executeCommands('savestate&val=u');" data-role="button">U</a> |
| 37 | <a href="javascript:executeCommands('savestate&val=v');" data-role="button">V</a> |
| 38 | <a href="javascript:executeCommands('savestate&val=w');" data-role="button">W</a> |
| 39 | <a href="javascript:executeCommands('savestate&val=x');" data-role="button">X</a> |
| 40 | <a href="javascript:executeCommands('savestate&val=y');" data-role="button">Y</a> |
| 41 | <a href="javascript:executeCommands('savestate&val=z');" data-role="button">Z</a> |
| 42 | |
| 43 | </div> |
| 44 | |
trunk/web/loadstate.html
| r0 | r25398 | |
| 1 | Select position to load from |
| 2 | <!-- Yes, it's a little ugly. I could redo this more cleanly with a little javascript, but not right now. --> |
| 3 | <div data-role="controlgroup" data-type="horizontal"> |
| 4 | <a href="javascript:loadContent('commands');" data-role="button">Cancel</a> |
| 5 | <a href="javascript:executeCommands('loadstate&val=auto');" data-role="button">Autosave Slot</a> |
| 6 | <a href="javascript:executeCommands('loadstate&val=0');" data-role="button">0</a> |
| 7 | <a href="javascript:executeCommands('loadstate&val=1');" data-role="button">1</a> |
| 8 | <a href="javascript:executeCommands('loadstate&val=2');" data-role="button">2</a> |
| 9 | <a href="javascript:executeCommands('loadstate&val=3');" data-role="button">3</a> |
| 10 | <a href="javascript:executeCommands('loadstate&val=4');" data-role="button">4</a> |
| 11 | <a href="javascript:executeCommands('loadstate&val=5');" data-role="button">5</a> |
| 12 | <a href="javascript:executeCommands('loadstate&val=6');" data-role="button">6</a> |
| 13 | <a href="javascript:executeCommands('loadstate&val=7');" data-role="button">7</a> |
| 14 | <a href="javascript:executeCommands('loadstate&val=8');" data-role="button">8</a> |
| 15 | <a href="javascript:executeCommands('loadstate&val=9');" data-role="button">9</a> |
| 16 | <a href="javascript:executeCommands('loadstate&val=a');" data-role="button">A</a> |
| 17 | <a href="javascript:executeCommands('loadstate&val=b');" data-role="button">B</a> |
| 18 | <a href="javascript:executeCommands('loadstate&val=c');" data-role="button">C</a> |
| 19 | <a href="javascript:executeCommands('loadstate&val=d');" data-role="button">D</a> |
| 20 | <a href="javascript:executeCommands('loadstate&val=e');" data-role="button">E</a> |
| 21 | <a href="javascript:executeCommands('loadstate&val=f');" data-role="button">F</a> |
| 22 | <a href="javascript:executeCommands('loadstate&val=g');" data-role="button">G</a> |
| 23 | <a href="javascript:executeCommands('loadstate&val=h');" data-role="button">H</a> |
| 24 | <a href="javascript:executeCommands('loadstate&val=i');" data-role="button">I</a> |
| 25 | <a href="javascript:executeCommands('loadstate&val=j');" data-role="button">J</a> |
| 26 | <a href="javascript:executeCommands('loadstate&val=k');" data-role="button">K</a> |
| 27 | <a href="javascript:executeCommands('loadstate&val=l');" data-role="button">L</a> |
| 28 | <a href="javascript:executeCommands('loadstate&val=m');" data-role="button">M</a> |
| 29 | <a href="javascript:executeCommands('loadstate&val=n');" data-role="button">N</a> |
| 30 | <a href="javascript:executeCommands('loadstate&val=o');" data-role="button">O</a> |
| 31 | <a href="javascript:executeCommands('loadstate&val=p');" data-role="button">P</a> |
| 32 | <a href="javascript:executeCommands('loadstate&val=q');" data-role="button">Q</a> |
| 33 | <a href="javascript:executeCommands('loadstate&val=r');" data-role="button">R</a> |
| 34 | <a href="javascript:executeCommands('loadstate&val=s');" data-role="button">S</a> |
| 35 | <a href="javascript:executeCommands('loadstate&val=t');" data-role="button">T</a> |
| 36 | <a href="javascript:executeCommands('loadstate&val=u');" data-role="button">U</a> |
| 37 | <a href="javascript:executeCommands('loadstate&val=v');" data-role="button">V</a> |
| 38 | <a href="javascript:executeCommands('loadstate&val=w');" data-role="button">W</a> |
| 39 | <a href="javascript:executeCommands('loadstate&val=x');" data-role="button">X</a> |
| 40 | <a href="javascript:executeCommands('loadstate&val=y');" data-role="button">Y</a> |
| 41 | <a href="javascript:executeCommands('loadstate&val=z');" data-role="button">Z</a> |
| 42 | |
| 43 | </div> |
| 44 | |