@@ -237,7 +237,8 @@ static uint16_t ducky_get_keycode(BadUsbScript* bad_usb, const char* param, bool
237237 return 0 ;
238238}
239239
240- static int32_t ducky_parse_line (BadUsbScript * bad_usb , string_t line ) {
240+ static int32_t
241+ ducky_parse_line (BadUsbScript * bad_usb , string_t line , char * error , size_t error_len ) {
241242 uint32_t line_len = string_size (line );
242243 const char * line_tmp = string_get_cstr (line );
243244 bool state = false;
@@ -270,24 +271,36 @@ static int32_t ducky_parse_line(BadUsbScript* bad_usb, string_t line) {
270271 if ((state ) && (delay_val > 0 )) {
271272 return (int32_t )delay_val ;
272273 }
274+ if (error != NULL ) {
275+ snprintf (error , error_len , "Invalid number %s" , line_tmp );
276+ }
273277 return SCRIPT_STATE_ERROR ;
274278 } else if (
275279 (strncmp (line_tmp , ducky_cmd_defdelay_1 , strlen (ducky_cmd_defdelay_1 )) == 0 ) ||
276280 (strncmp (line_tmp , ducky_cmd_defdelay_2 , strlen (ducky_cmd_defdelay_2 )) == 0 )) {
277281 // DEFAULT_DELAY
278282 line_tmp = & line_tmp [ducky_get_command_len (line_tmp ) + 1 ];
279283 state = ducky_get_number (line_tmp , & bad_usb -> defdelay );
284+ if (!state && error != NULL ) {
285+ snprintf (error , error_len , "Invalid number %s" , line_tmp );
286+ }
280287 return (state ) ? (0 ) : SCRIPT_STATE_ERROR ;
281288 } else if (strncmp (line_tmp , ducky_cmd_string , strlen (ducky_cmd_string )) == 0 ) {
282289 // STRING
283290 line_tmp = & line_tmp [ducky_get_command_len (line_tmp ) + 1 ];
284291 state = ducky_string (bad_usb , line_tmp );
292+ if (!state && error != NULL ) {
293+ snprintf (error , error_len , "Invalid string %s" , line_tmp );
294+ }
285295 return (state ) ? (0 ) : SCRIPT_STATE_ERROR ;
286296 } else if (strncmp (line_tmp , ducky_cmd_altchar , strlen (ducky_cmd_altchar )) == 0 ) {
287297 // ALTCHAR
288298 line_tmp = & line_tmp [ducky_get_command_len (line_tmp ) + 1 ];
289299 ducky_numlock_on ();
290300 state = ducky_altchar (line_tmp );
301+ if (!state && error != NULL ) {
302+ snprintf (error , error_len , "Invalid altchar %s" , line_tmp );
303+ }
291304 return (state ) ? (0 ) : SCRIPT_STATE_ERROR ;
292305 } else if (
293306 (strncmp (line_tmp , ducky_cmd_altstr_1 , strlen (ducky_cmd_altstr_1 )) == 0 ) ||
@@ -296,11 +309,17 @@ static int32_t ducky_parse_line(BadUsbScript* bad_usb, string_t line) {
296309 line_tmp = & line_tmp [ducky_get_command_len (line_tmp ) + 1 ];
297310 ducky_numlock_on ();
298311 state = ducky_altstring (line_tmp );
312+ if (!state && error != NULL ) {
313+ snprintf (error , error_len , "Invalid altstring %s" , line_tmp );
314+ }
299315 return (state ) ? (0 ) : SCRIPT_STATE_ERROR ;
300316 } else if (strncmp (line_tmp , ducky_cmd_repeat , strlen (ducky_cmd_repeat )) == 0 ) {
301317 // REPEAT
302318 line_tmp = & line_tmp [ducky_get_command_len (line_tmp ) + 1 ];
303319 state = ducky_get_number (line_tmp , & bad_usb -> repeat_cnt );
320+ if (!state && error != NULL ) {
321+ snprintf (error , error_len , "Invalid number %s" , line_tmp );
322+ }
304323 return (state ) ? (0 ) : SCRIPT_STATE_ERROR ;
305324 } else if (strncmp (line_tmp , ducky_cmd_sysrq , strlen (ducky_cmd_sysrq )) == 0 ) {
306325 // SYSRQ
@@ -313,7 +332,12 @@ static int32_t ducky_parse_line(BadUsbScript* bad_usb, string_t line) {
313332 } else {
314333 // Special keys + modifiers
315334 uint16_t key = ducky_get_keycode (bad_usb , line_tmp , false);
316- if (key == HID_KEYBOARD_NONE ) return SCRIPT_STATE_ERROR ;
335+ if (key == HID_KEYBOARD_NONE ) {
336+ if (error != NULL ) {
337+ snprintf (error , error_len , "No keycode defined for %s" , line_tmp );
338+ }
339+ return SCRIPT_STATE_ERROR ;
340+ }
317341 if ((key & 0xFF00 ) != 0 ) {
318342 // It's a modifier key
319343 line_tmp = & line_tmp [ducky_get_command_len (line_tmp ) + 1 ];
@@ -323,6 +347,9 @@ static int32_t ducky_parse_line(BadUsbScript* bad_usb, string_t line) {
323347 furi_hal_hid_kb_release (key );
324348 return (0 );
325349 }
350+ if (error != NULL ) {
351+ strncpy (error , "Unknown error" , error_len );
352+ }
326353 return SCRIPT_STATE_ERROR ;
327354}
328355
@@ -401,7 +428,8 @@ static int32_t ducky_script_execute_next(BadUsbScript* bad_usb, File* script_fil
401428
402429 if (bad_usb -> repeat_cnt > 0 ) {
403430 bad_usb -> repeat_cnt -- ;
404- delay_val = ducky_parse_line (bad_usb , bad_usb -> line_prev );
431+ delay_val = ducky_parse_line (
432+ bad_usb , bad_usb -> line_prev , bad_usb -> st .error , sizeof (bad_usb -> st .error ));
405433 if (delay_val == SCRIPT_STATE_NEXT_LINE ) { // Empty line
406434 return 0 ;
407435 } else if (delay_val < 0 ) { // Script error
@@ -435,10 +463,20 @@ static int32_t ducky_script_execute_next(BadUsbScript* bad_usb, File* script_fil
435463 bad_usb -> st .line_cur ++ ;
436464 bad_usb -> buf_len = bad_usb -> buf_len + bad_usb -> buf_start - (i + 1 );
437465 bad_usb -> buf_start = i + 1 ;
438- delay_val = ducky_parse_line (bad_usb , bad_usb -> line );
466+ delay_val = ducky_parse_line (
467+ bad_usb , bad_usb -> line , bad_usb -> st .error , sizeof (bad_usb -> st .error ));
468+
439469 if (delay_val < 0 ) {
440470 bad_usb -> st .error_line = bad_usb -> st .line_cur ;
441- FURI_LOG_E (WORKER_TAG , "Unknown command at line %lu" , bad_usb -> st .line_cur );
471+ if (delay_val == SCRIPT_STATE_NEXT_LINE ) {
472+ snprintf (
473+ bad_usb -> st .error , sizeof (bad_usb -> st .error ), "Forbidden empty line" );
474+ FURI_LOG_E (
475+ WORKER_TAG , "Forbidden empty line at line %lu" , bad_usb -> st .line_cur );
476+ } else {
477+ FURI_LOG_E (
478+ WORKER_TAG , "Unknown command at line %lu" , bad_usb -> st .line_cur );
479+ }
442480 return SCRIPT_STATE_ERROR ;
443481 } else {
444482 return (delay_val + bad_usb -> defdelay );
@@ -618,6 +656,7 @@ BadUsbScript* bad_usb_script_open(string_t file_path) {
618656 bad_usb_script_set_default_keyboard_layout (bad_usb );
619657
620658 bad_usb -> st .state = BadUsbStateInit ;
659+ bad_usb -> st .error [0 ] = '\0' ;
621660
622661 bad_usb -> thread = furi_thread_alloc ();
623662 furi_thread_set_name (bad_usb -> thread , "BadUsbWorker" );
0 commit comments