| 490 | } |
| 491 | |
| 492 | bool ShortcutCreationDialog::EscapeShortcutCommandLine(std::string* arg) |
| 493 | { |
| 494 | #ifdef _WIN32 |
| 495 | if (!arg->empty() && arg->find_first_of(" \t\n\v\"") == std::string::npos) |
| 496 | return true; |
| 497 | |
| 498 | std::string temp; |
| 499 | temp.reserve(arg->length() + 10); |
| 500 | temp += '"'; |
| 501 | |
| 502 | for (auto it = arg->begin();; ++it) |
| 503 | { |
| 504 | int backslash_count = 0; |
| 505 | while (it != arg->end() && *it == '\\') |
| 506 | { |
| 507 | ++it; |
| 508 | ++backslash_count; |
| 509 | } |
| 510 | |
| 511 | if (it == arg->end()) |
| 512 | { |
| 513 | temp.append(backslash_count * 2, '\\'); |
| 514 | break; |
| 515 | } |
| 516 | |
| 517 | if (*it == '"') |
| 518 | { |
| 519 | temp.append(backslash_count * 2 + 1, '\\'); |
| 520 | temp += '"'; |
| 521 | } |
| 522 | else |
| 523 | { |
| 524 | temp.append(backslash_count, '\\'); |
| 525 | temp += *it; |
| 526 | } |
| 527 | } |
| 528 | |
| 529 | temp += '"'; |
| 530 | *arg = std::move(temp); |
| 531 | return true; |
| 532 | #else |
| 533 | const char* carg = arg->c_str(); |
| 534 | const char* cend = carg + arg->size(); |
| 535 | const char* RESERVED_CHARS = " \t\n\\\"'\\\\><~|%&;$*?#()`" |
| 536 | "\x01\x02\x03\x04\x05\x06\x07\x08\x0b\x0c\x0d\x0e\x0f" |
| 537 | "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x7f"; |
| 538 | const char* next = carg + std::strcspn(carg, RESERVED_CHARS); |
| 539 | |
| 540 | if (next == cend) |
| 541 | return true; // No escaping needed, don't modify |
| 542 | |
| 543 | bool lossless = true; |
| 544 | std::string temp = "\""; |
| 545 | const char* NOT_VALID_IN_QUOTE = "%`$\"\\\n" |
| 546 | "\x01\x02\x03\x04\x05\x06\x07\x08\x0b\x0c\x0d\x0e\x0f" |
| 547 | "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x7f"; |
| 548 | |
| 549 | while (true) |