| 878 | } |
| 879 | |
| 880 | std::string parse_env_val(boost::process::v1::native_environment &env, const std::string_view &val_raw) { |
| 881 | auto pos = std::begin(val_raw); |
| 882 | auto dollar = std::find(pos, std::end(val_raw), '$'); |
| 883 | |
| 884 | std::stringstream ss; |
| 885 | |
| 886 | while (dollar != std::end(val_raw)) { |
| 887 | auto next = dollar + 1; |
| 888 | if (next != std::end(val_raw)) { |
| 889 | switch (*next) { |
| 890 | case '(': |
| 891 | { |
| 892 | ss.write(pos, (dollar - pos)); |
| 893 | auto var_begin = next + 1; |
| 894 | auto var_end = find_match(next, std::end(val_raw)); |
| 895 | auto var_name = std::string {var_begin, var_end}; |
| 896 | |
| 897 | #ifdef _WIN32 |
| 898 | // Windows treats environment variable names in a case-insensitive manner, |
| 899 | // so we look for a case-insensitive match here. This is critical for |
| 900 | // correctly appending to PATH on Windows. |
| 901 | auto itr = std::find_if(env.cbegin(), env.cend(), [&](const auto &e) { |
| 902 | return boost::iequals(e.get_name(), var_name); |
| 903 | }); |
| 904 | if (itr != env.cend()) { |
| 905 | // Use an existing case-insensitive match |
| 906 | var_name = itr->get_name(); |
| 907 | } |
| 908 | #endif |
| 909 | |
| 910 | ss << env[var_name].to_string(); |
| 911 | |
| 912 | pos = var_end + 1; |
| 913 | next = var_end; |
| 914 | |
| 915 | break; |
| 916 | } |
| 917 | case '$': |
| 918 | ss.write(pos, (next - pos)); |
| 919 | pos = next + 1; |
| 920 | ++next; |
| 921 | break; |
| 922 | } |
| 923 | |
| 924 | dollar = std::find(next, std::end(val_raw), '$'); |
| 925 | } else { |
| 926 | dollar = next; |
| 927 | } |
| 928 | } |
| 929 | |
| 930 | ss.write(pos, (dollar - pos)); |
| 931 | |
| 932 | return ss.str(); |
| 933 | } |
| 934 | |
| 935 | std::string validate_app_image_path(std::string app_image_path) { |
| 936 | if (app_image_path.empty()) { |