wchar_t* make_program_args(char** args, int verbatim_arguments) { wchar_t* dst; wchar_t* ptr; char** arg; size_t size = 0; size_t len; int arg_count = 0; wchar_t* buffer; int arg_size; int buffer_size = 0; /* Count the required size. */ for (arg = args; *arg; arg++) { arg_size = uv_utf8_to_utf16(*arg, NULL, 0) * sizeof(wchar_t); size += arg_size; buffer_size = arg_size > buffer_size ? arg_size : buffer_size; arg_count++; } /* Adjust for potential quotes. Also assume the worst-case scenario /* that every character needs escaping, so we need twice as much space. */ size = size * 2 + arg_count * 2; dst = (wchar_t*)malloc(size); if (!dst) { uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); } buffer = (wchar_t*)malloc(buffer_size); if (!buffer) { uv_fatal_error(ERROR_OUTOFMEMORY, "malloc"); } ptr = dst; for (arg = args; *arg; arg++) { len = uv_utf8_to_utf16(*arg, buffer, (size_t)(size - (ptr - dst))); if (!len) { goto error; } if (verbatim_arguments) { wcscpy(ptr, buffer); ptr += len - 1; } else { ptr = quote_cmd_arg(buffer, ptr); } *ptr++ = *(arg + 1) ? L' ' : L'\0'; } free(buffer); return dst; error: free(dst); free(buffer); return NULL; }
uv_err_t make_program_args(char** args, int verbatim_arguments, WCHAR** dst_ptr) { char** arg; WCHAR* dst = NULL; WCHAR* temp_buffer = NULL; size_t dst_len = 0; size_t temp_buffer_len = 0; WCHAR* pos; int arg_count = 0; uv_err_t err = uv_ok_; /* Count the required size. */ for (arg = args; *arg; arg++) { DWORD arg_len; arg_len = MultiByteToWideChar(CP_UTF8, 0, *arg, -1, NULL, 0); if (arg_len == 0) { return uv__new_sys_error(GetLastError()); } dst_len += arg_len; if (arg_len > temp_buffer_len) temp_buffer_len = arg_len; arg_count++; } /* Adjust for potential quotes. Also assume the worst-case scenario */ /* that every character needs escaping, so we need twice as much space. */ dst_len = dst_len * 2 + arg_count * 2; /* Allocate buffer for the final command line. */ dst = (WCHAR*) malloc(dst_len * sizeof(WCHAR)); if (dst == NULL) { err = uv__new_artificial_error(UV_ENOMEM); goto error; } /* Allocate temporary working buffer. */ temp_buffer = (WCHAR*) malloc(temp_buffer_len * sizeof(WCHAR)); if (temp_buffer == NULL) { err = uv__new_artificial_error(UV_ENOMEM); goto error; } pos = dst; for (arg = args; *arg; arg++) { DWORD arg_len; /* Convert argument to wide char. */ arg_len = MultiByteToWideChar(CP_UTF8, 0, *arg, -1, temp_buffer, dst + dst_len - pos); if (arg_len == 0) { goto error; } if (verbatim_arguments) { /* Copy verbatim. */ wcscpy(pos, temp_buffer); pos += arg_len - 1; } else { /* Quote/escape, if needed. */ pos = quote_cmd_arg(temp_buffer, pos); } *pos++ = *(arg + 1) ? L' ' : L'\0'; } free(temp_buffer); *dst_ptr = dst; return uv_ok_; error: free(dst); free(temp_buffer); return err; }