Reference re-parser: the subset of CommandLineToArgvW our builder emits (every * arg quote-wrapped; \" for embedded quotes; backslashes doubled before a quote). */
| 838 | /* Reference re-parser: the subset of CommandLineToArgvW our builder emits (every |
| 839 | * arg quote-wrapped; \" for embedded quotes; backslashes doubled before a quote). */ |
| 840 | static int parse_win_cmdline(const char *cmd, char out[][256], int max_args) { |
| 841 | int argc = 0; |
| 842 | const char *p = cmd; |
| 843 | while (*p) { |
| 844 | while (*p == ' ' || *p == '\t') { |
| 845 | p++; |
| 846 | } |
| 847 | if (!*p || argc >= max_args) { |
| 848 | break; |
| 849 | } |
| 850 | char *o = out[argc]; |
| 851 | size_t oi = 0; |
| 852 | bool in_quotes = false; |
| 853 | /* Guard every write: each out[] row is 256 bytes; test args stay well under |
| 854 | * that, but cap defensively so a future longer arg fails a length assertion |
| 855 | * rather than smashing the stack. */ |
| 856 | #define PUTO(ch) \ |
| 857 | do { \ |
| 858 | if (oi < 255) { \ |
| 859 | o[oi++] = (ch); \ |
| 860 | } \ |
| 861 | } while (0) |
| 862 | for (;;) { |
| 863 | size_t nbs = 0; |
| 864 | while (*p == '\\') { |
| 865 | nbs++; |
| 866 | p++; |
| 867 | } |
| 868 | if (*p == '"') { |
| 869 | for (size_t k = 0; k < nbs / 2; k++) { |
| 870 | PUTO('\\'); |
| 871 | } |
| 872 | if (nbs % 2) { |
| 873 | PUTO('"'); /* odd run → the quote is an escaped literal */ |
| 874 | } else { |
| 875 | in_quotes = !in_quotes; /* even run → the quote is a delimiter */ |
| 876 | } |
| 877 | p++; |
| 878 | } else { |
| 879 | for (size_t k = 0; k < nbs; k++) { |
| 880 | PUTO('\\'); |
| 881 | } |
| 882 | if (*p == '\0' || (!in_quotes && (*p == ' ' || *p == '\t'))) { |
| 883 | break; |
| 884 | } |
| 885 | PUTO(*p); |
| 886 | p++; |
| 887 | } |
| 888 | } |
| 889 | #undef PUTO |
| 890 | o[oi] = '\0'; |
| 891 | argc++; |
| 892 | } |
| 893 | return argc; |
| 894 | } |
| 895 | |
| 896 | static bool cmdline_roundtrips(const char *const *argv) { |
| 897 | char cmd[4096]; |
no outgoing calls
no test coverage detected