| 612 | } |
| 613 | |
| 614 | bool |
| 615 | appendShellStringNoError(PQExpBuffer buf, const char *str) |
| 616 | { |
| 617 | #ifdef WIN32 |
| 618 | int backslash_run_length = 0; |
| 619 | #endif |
| 620 | bool ok = true; |
| 621 | const char *p; |
| 622 | |
| 623 | /* |
| 624 | * Don't bother with adding quotes if the string is nonempty and clearly |
| 625 | * contains only safe characters. |
| 626 | */ |
| 627 | if (*str != '\0' && |
| 628 | strspn(str, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_./:") == strlen(str)) |
| 629 | { |
| 630 | appendPQExpBufferStr(buf, str); |
| 631 | return ok; |
| 632 | } |
| 633 | |
| 634 | #ifndef WIN32 |
| 635 | appendPQExpBufferChar(buf, '\''); |
| 636 | for (p = str; *p; p++) |
| 637 | { |
| 638 | if (*p == '\n' || *p == '\r') |
| 639 | { |
| 640 | ok = false; |
| 641 | continue; |
| 642 | } |
| 643 | |
| 644 | if (*p == '\'') |
| 645 | appendPQExpBufferStr(buf, "'\"'\"'"); |
| 646 | else |
| 647 | appendPQExpBufferChar(buf, *p); |
| 648 | } |
| 649 | appendPQExpBufferChar(buf, '\''); |
| 650 | #else /* WIN32 */ |
| 651 | |
| 652 | /* |
| 653 | * A Windows system() argument experiences two layers of interpretation. |
| 654 | * First, cmd.exe interprets the string. Its behavior is undocumented, |
| 655 | * but a caret escapes any byte except LF or CR that would otherwise have |
| 656 | * special meaning. Handling of a caret before LF or CR differs between |
| 657 | * "cmd.exe /c" and other modes, and it is unusable here. |
| 658 | * |
| 659 | * Second, the new process parses its command line to construct argv (see |
| 660 | * https://msdn.microsoft.com/en-us/library/17w5ykft.aspx). This treats |
| 661 | * backslash-double quote sequences specially. |
| 662 | */ |
| 663 | appendPQExpBufferStr(buf, "^\""); |
| 664 | for (p = str; *p; p++) |
| 665 | { |
| 666 | if (*p == '\n' || *p == '\r') |
| 667 | { |
| 668 | ok = false; |
| 669 | continue; |
| 670 | } |
| 671 |
no test coverage detected