From: Anatol Belski Date: Mon, 17 Sep 2018 07:48:33 +0000 (+0200) Subject: Fix localized error messages and memory leaks X-Git-Tag: php-7.4.0alpha1~1903 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=321c0cc3493998f731f0666127c093eff4e119eb;p=php Fix localized error messages and memory leaks The FormatMessage API needs to LocalFree the delivered error messages. In cases where messages are delivered in non ASCII compatible encoding, the messages might be unreadable. This aligns the error message encoding with the encoding settings in PHP, the focus is UTF-8 as default. Initialize error buffer Avoid code duplication --- diff --git a/Zend/zend_alloc.c b/Zend/zend_alloc.c index c1250d1e78..d3b2461201 100644 --- a/Zend/zend_alloc.c +++ b/Zend/zend_alloc.c @@ -68,6 +68,7 @@ #ifdef ZEND_WIN32 # include # include +# include "win32/winutil.h" #endif #include @@ -394,23 +395,17 @@ static ZEND_COLD ZEND_NORETURN void zend_mm_safe_error(zend_mm_heap *heap, void stderr_last_error(char *msg) { - LPSTR buf = NULL; DWORD err = GetLastError(); + char *buf = php_win32_error_to_msg(err); - if (!FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - err, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPSTR)&buf, - 0, NULL)) { + if (!buf[0]) { fprintf(stderr, "\n%s: [0x%08lx]\n", msg, err); } else { fprintf(stderr, "\n%s: [0x%08lx] %s\n", msg, err, buf); } + + php_win32_error_msg_free(buf); } #endif diff --git a/ext/com_dotnet/com_com.c b/ext/com_dotnet/com_com.c index eb79ed76ff..5ddf3358c5 100644 --- a/ext/com_dotnet/com_com.c +++ b/ext/com_dotnet/com_com.c @@ -231,7 +231,7 @@ PHP_FUNCTION(com_create_instance) werr = php_win32_error_to_msg(res); spprintf(&msg, 0, "Failed to create COM object `%s': %s", module_name, werr); - LocalFree(werr); + php_win32_error_msg_free(werr); php_com_throw_exception(res, msg); efree(msg); @@ -389,7 +389,7 @@ HRESULT php_com_invoke_helper(php_com_dotnet_object *obj, DISPID id_member, case DISP_E_TYPEMISMATCH: desc = php_win32_error_to_msg(hr); spprintf(&msg, 0, "Parameter %d: %s", arg_err, desc); - LocalFree(desc); + php_win32_error_msg_free(desc); break; case DISP_E_BADPARAMCOUNT: @@ -405,7 +405,7 @@ HRESULT php_com_invoke_helper(php_com_dotnet_object *obj, DISPID id_member, default: desc = php_win32_error_to_msg(hr); spprintf(&msg, 0, "Error [0x%08x] %s", hr, desc); - LocalFree(desc); + php_win32_error_msg_free(desc); break; } @@ -485,11 +485,10 @@ int php_com_do_invoke_byref(php_com_dotnet_object *obj, zend_internal_function * hr = php_com_get_id_of_name(obj, f->function_name->val, f->function_name->len, &dispid); if (FAILED(hr)) { - char *winerr = NULL; char *msg = NULL; - winerr = php_win32_error_to_msg(hr); + char *winerr = php_win32_error_to_msg(hr); spprintf(&msg, 0, "Unable to lookup `%s': %s", f->function_name->val, winerr); - LocalFree(winerr); + php_win32_error_msg_free(winerr); php_com_throw_exception(hr, msg); efree(msg); return FAILURE; @@ -648,15 +647,14 @@ int php_com_do_invoke(php_com_dotnet_object *obj, char *name, size_t namelen, { DISPID dispid; HRESULT hr; - char *winerr = NULL; char *msg = NULL; hr = php_com_get_id_of_name(obj, name, namelen, &dispid); if (FAILED(hr)) { - winerr = php_win32_error_to_msg(hr); + char *winerr = php_win32_error_to_msg(hr); spprintf(&msg, 0, "Unable to lookup `%s': %s", name, winerr); - LocalFree(winerr); + php_win32_error_msg_free(winerr); php_com_throw_exception(hr, msg); efree(msg); return FAILURE; diff --git a/ext/com_dotnet/com_dotnet.c b/ext/com_dotnet/com_dotnet.c index f8bdefdf21..f522436365 100644 --- a/ext/com_dotnet/com_dotnet.c +++ b/ext/com_dotnet/com_dotnet.c @@ -205,8 +205,7 @@ PHP_FUNCTION(com_dotnet_create_instance) char buf[1024]; char *err = php_win32_error_to_msg(hr); snprintf(buf, sizeof(buf), "Failed to init .Net runtime [%s] %s", where, err); - if (err) - LocalFree(err); + php_win32_error_msg_free(err); php_com_throw_exception(hr, buf); return; } @@ -219,8 +218,7 @@ PHP_FUNCTION(com_dotnet_create_instance) char buf[1024]; char *err = php_win32_error_to_msg(hr); snprintf(buf, sizeof(buf), "Failed to re-init .Net domain [%s] %s", where, err); - if (err) - LocalFree(err); + php_win32_error_msg_free(err); php_com_throw_exception(hr, buf); ZVAL_NULL(object); return; @@ -232,8 +230,7 @@ PHP_FUNCTION(com_dotnet_create_instance) char buf[1024]; char *err = php_win32_error_to_msg(hr); snprintf(buf, sizeof(buf), "Failed to re-init .Net domain [%s] %s", where, err); - if (err) - LocalFree(err); + php_win32_error_msg_free(err); php_com_throw_exception(hr, buf); ZVAL_NULL(object); return; @@ -315,9 +312,7 @@ PHP_FUNCTION(com_dotnet_create_instance) char buf[1024]; char *err = php_win32_error_to_msg(hr); snprintf(buf, sizeof(buf), "Failed to instantiate .Net object [%s] [0x%08x] %s", where, hr, err); - if (err && err[0]) { - LocalFree(err); - } + php_win32_error_msg_free(err); php_com_throw_exception(hr, buf); return; } diff --git a/ext/com_dotnet/com_misc.c b/ext/com_dotnet/com_misc.c index 6488b3c8b4..c534117f9d 100644 --- a/ext/com_dotnet/com_misc.c +++ b/ext/com_dotnet/com_misc.c @@ -40,7 +40,7 @@ void php_com_throw_exception(HRESULT code, char *message) zend_throw_exception(php_com_exception_class_entry, message, (zend_long)code); #endif if (free_msg) { - LocalFree(message); + php_win32_error_msg_free(message); } } diff --git a/ext/com_dotnet/com_olechar.c b/ext/com_dotnet/com_olechar.c index b9a332e4f5..c586756ad7 100644 --- a/ext/com_dotnet/com_olechar.c +++ b/ext/com_dotnet/com_olechar.c @@ -63,7 +63,7 @@ PHP_COM_DOTNET_API OLECHAR *php_com_string_to_olestring(char *string, size_t str php_error_docref(NULL, E_WARNING, "Could not convert string to unicode: `%s'", msg); - LocalFree(msg); + php_win32_error_msg_free(msg); } return olestring; @@ -94,7 +94,7 @@ PHP_COM_DOTNET_API char *php_com_olestring_to_string(OLECHAR *olestring, size_t php_error_docref(NULL, E_WARNING, "Could not convert string from unicode: `%s'", msg); - LocalFree(msg); + php_win32_error_msg_free(msg); } if (string_len) { diff --git a/ext/com_dotnet/com_variant.c b/ext/com_dotnet/com_variant.c index 170f15b6e7..e2b515caad 100644 --- a/ext/com_dotnet/com_variant.c +++ b/ext/com_dotnet/com_variant.c @@ -490,7 +490,7 @@ PHP_FUNCTION(com_variant_create_instance) werr = php_win32_error_to_msg(res); spprintf(&msg, 0, "Variant type conversion failed: %s", werr); - LocalFree(werr); + php_win32_error_msg_free(werr); php_com_throw_exception(res, msg); efree(msg); @@ -1078,7 +1078,7 @@ PHP_FUNCTION(variant_set_type) werr = php_win32_error_to_msg(res); spprintf(&msg, 0, "Variant type conversion failed: %s", werr); - LocalFree(werr); + php_win32_error_msg_free(werr); php_com_throw_exception(res, msg); efree(msg); @@ -1112,7 +1112,7 @@ PHP_FUNCTION(variant_cast) werr = php_win32_error_to_msg(res); spprintf(&msg, 0, "Variant type conversion failed: %s", werr); - LocalFree(werr); + php_win32_error_msg_free(werr); php_com_throw_exception(res, msg); efree(msg); diff --git a/ext/opcache/shared_alloc_win32.c b/ext/opcache/shared_alloc_win32.c index 5207a59812..9179755849 100644 --- a/ext/opcache/shared_alloc_win32.c +++ b/ext/opcache/shared_alloc_win32.c @@ -23,6 +23,7 @@ #include "zend_shared_alloc.h" #include "zend_accelerator_util_funcs.h" #include "tsrm_win32.h" +#include "win32/winutil.h" #include #include #include @@ -40,25 +41,13 @@ static void *mapping_base; static void zend_win_error_message(int type, char *msg, int err) { - LPVOID lpMsgBuf; HANDLE h; char *ev_msgs[2]; - - FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - err, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language - (LPTSTR) &lpMsgBuf, - 0, - NULL - ); + char *buf = php_win32_error_to_msg(err); h = RegisterEventSource(NULL, TEXT(ACCEL_EVENT_SOURCE)); ev_msgs[0] = msg; - ev_msgs[1] = lpMsgBuf; + ev_msgs[1] = buf; ReportEvent(h, // event log handle EVENTLOG_ERROR_TYPE, // event type 0, // category zero @@ -70,9 +59,9 @@ static void zend_win_error_message(int type, char *msg, int err) NULL); // pointer to data DeregisterEventSource(h); - LocalFree( lpMsgBuf ); - zend_accel_error(type, "%s", msg); + + php_win32_error_msg_free(buf); } static char *create_name_with_username(char *name) diff --git a/ext/openssl/xp_ssl.c b/ext/openssl/xp_ssl.c index 11bea41295..4c4bfaddd3 100644 --- a/ext/openssl/xp_ssl.c +++ b/ext/openssl/xp_ssl.c @@ -637,7 +637,9 @@ static int php_openssl_win_cert_verify_callback(X509_STORE_CTX *x509_store_ctx, OPENSSL_free(der_buf); if (cert_ctx == NULL) { - php_error_docref(NULL, E_WARNING, "Error creating certificate context: %s", php_win_err()); + char *err = php_win_err(); + php_error_docref(NULL, E_WARNING, "Error creating certificate context: %s", err); + php_win_err_free(err); RETURN_CERT_VERIFY_FAILURE(SSL_R_CERTIFICATE_VERIFY_FAILED); } } @@ -659,7 +661,9 @@ static int php_openssl_win_cert_verify_callback(X509_STORE_CTX *x509_store_ctx, chain_flags = CERT_CHAIN_CACHE_END_CERT | CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT; if (!CertGetCertificateChain(NULL, cert_ctx, NULL, NULL, &chain_params, chain_flags, NULL, &cert_chain_ctx)) { - php_error_docref(NULL, E_WARNING, "Error getting certificate chain: %s", php_win_err()); + char *err = php_win_err(); + php_error_docref(NULL, E_WARNING, "Error getting certificate chain: %s", err); + php_win_err_free(err); CertFreeCertificateContext(cert_ctx); RETURN_CERT_VERIFY_FAILURE(SSL_R_CERTIFICATE_VERIFY_FAILED); } @@ -743,7 +747,9 @@ static int php_openssl_win_cert_verify_callback(X509_STORE_CTX *x509_store_ctx, CertFreeCertificateContext(cert_ctx); if (!verify_result) { - php_error_docref(NULL, E_WARNING, "Error verifying certificate chain policy: %s", php_win_err()); + char *err = php_win_err(); + php_error_docref(NULL, E_WARNING, "Error verifying certificate chain policy: %s", err); + php_win_err_free(err); RETURN_CERT_VERIFY_FAILURE(SSL_R_CERTIFICATE_VERIFY_FAILED); } diff --git a/ext/sockets/sockets.c b/ext/sockets/sockets.c index e8e689f83a..748f210128 100644 --- a/ext/sockets/sockets.c +++ b/ext/sockets/sockets.c @@ -37,6 +37,7 @@ # include # include "php_sockets.h" # include +# include #else # include # include @@ -649,12 +650,10 @@ char *sockets_strerror(int error) /* {{{ */ } #else { - LPTSTR tmp = NULL; + char *tmp = php_win32_error_to_msg(error); buf = NULL; - if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &tmp, 0, NULL) - ) { + if (tmp[0]) { if (SOCKETS_G(strerror_buf)) { efree(SOCKETS_G(strerror_buf)); } @@ -2822,22 +2821,16 @@ PHP_FUNCTION(socket_wsaprotocol_info_export) if (SOCKET_ERROR == WSADuplicateSocket(socket->bsd_socket, (DWORD)target_pid, &wi)) { DWORD err = WSAGetLastError(); - LPSTR buf = NULL; - - if (!FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - err, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPSTR)&buf, - 0, NULL)) { + char *buf = php_win32_error_to_msg(err); + + if (!buf[0]) { php_error_docref(NULL, E_WARNING, "Unable to export WSA protocol info [0x%08lx]", err); } else { php_error_docref(NULL, E_WARNING, "Unable to export WSA protocol info [0x%08lx]: %s", err, buf); } + php_win32_error_msg_free(buf); + RETURN_FALSE; } @@ -2900,22 +2893,16 @@ PHP_FUNCTION(socket_wsaprotocol_info_import) sock = WSASocket(FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO, &wi, 0, 0); if (INVALID_SOCKET == sock) { DWORD err = WSAGetLastError(); - LPSTR buf = NULL; - - if (!FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - err, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPSTR)&buf, - 0, NULL)) { + char *buf = php_win32_error_to_msg(err); + + if (!buf[0]) { php_error_docref(NULL, E_WARNING, "Unable to import WSA protocol info [0x%08lx]", err); } else { php_error_docref(NULL, E_WARNING, "Unable to import WSA protocol info [0x%08lx]: %s", err, buf); } + php_win32_error_msg_free(buf); + RETURN_FALSE; } diff --git a/ext/standard/dl.c b/ext/standard/dl.c index 6b50f22bf4..5ac18f126f 100644 --- a/ext/standard/dl.c +++ b/ext/standard/dl.c @@ -88,7 +88,7 @@ PHPAPI void *php_load_shlib(char *path, char **errp) if (err && (*err)) { size_t i = strlen(err); (*errp)=estrdup(err); - LocalFree(err); + php_win32_error_msg_free(err); while (i > 0 && isspace((*errp)[i-1])) { (*errp)[i-1] = '\0'; i--; } } else { (*errp) = estrdup(""); diff --git a/ext/standard/exec.c b/ext/standard/exec.c index d914a1fd72..5b885c554d 100644 --- a/ext/standard/exec.c +++ b/ext/standard/exec.c @@ -564,7 +564,9 @@ PHP_FUNCTION(proc_nice) php_ignore_value(nice(pri)); if (errno) { #ifdef PHP_WIN32 - php_error_docref(NULL, E_WARNING, "%s", php_win_err()); + char *err = php_win_err(); + php_error_docref(NULL, E_WARNING, "%s", err); + php_win_err_free(err); #else php_error_docref(NULL, E_WARNING, "Only a super user may attempt to increase the priority of a process"); #endif diff --git a/ext/standard/filestat.c b/ext/standard/filestat.c index 3a3c024b6a..6073922f38 100644 --- a/ext/standard/filestat.c +++ b/ext/standard/filestat.c @@ -114,7 +114,9 @@ static int php_disk_total_space(char *path, double *space) /* {{{ */ PHP_WIN32_IOUTIL_INIT_W(path) if (GetDiskFreeSpaceExW(pathw, &FreeBytesAvailableToCaller, &TotalNumberOfBytes, &TotalNumberOfFreeBytes) == 0) { - php_error_docref(NULL, E_WARNING, "%s", php_win_err()); + char *err = php_win_err(); + php_error_docref(NULL, E_WARNING, "%s", err); + php_win_err_free(err); PHP_WIN32_IOUTIL_CLEANUP_W() return FAILURE; } @@ -208,7 +210,9 @@ static int php_disk_free_space(char *path, double *space) /* {{{ */ PHP_WIN32_IOUTIL_INIT_W(path) if (GetDiskFreeSpaceExW(pathw, &FreeBytesAvailableToCaller, &TotalNumberOfBytes, &TotalNumberOfFreeBytes) == 0) { - php_error_docref(NULL, E_WARNING, "%s", php_win_err()); + char *err = php_win_err(); + php_error_docref(NULL, E_WARNING, "%s", err); + php_win_err_free(err); PHP_WIN32_IOUTIL_CLEANUP_W() return FAILURE; } diff --git a/ext/standard/var_unserializer.c b/ext/standard/var_unserializer.c index 518277ca00..3c1c18a700 100644 --- a/ext/standard/var_unserializer.c +++ b/ext/standard/var_unserializer.c @@ -1,4 +1,4 @@ -/* Generated by re2c 1.0.1 */ +/* Generated by re2c 1.0.3 */ #line 1 "ext/standard/var_unserializer.re" /* +----------------------------------------------------------------------+ diff --git a/main/main.c b/main/main.c index c9c05dece5..e77ec61ca8 100644 --- a/main/main.c +++ b/main/main.c @@ -1162,24 +1162,18 @@ PHPAPI ZEND_COLD void php_error_docref2(const char *docref, const char *param1, /* }}} */ #ifdef PHP_WIN32 -#define PHP_WIN32_ERROR_MSG_BUFFER_SIZE 512 PHPAPI ZEND_COLD void php_win32_docref2_from_error(DWORD error, const char *param1, const char *param2) { - if (error == 0) { - php_error_docref2(NULL, param1, param2, E_WARNING, "%s", strerror(errno)); - } else { - char buf[PHP_WIN32_ERROR_MSG_BUFFER_SIZE + 1]; - size_t buf_len; - - FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, 0, buf, PHP_WIN32_ERROR_MSG_BUFFER_SIZE, NULL); - buf_len = strlen(buf); - if (buf_len >= 2) { - buf[buf_len - 1] = '\0'; - buf[buf_len - 2] = '\0'; - } - php_error_docref2(NULL, param1, param2, E_WARNING, "%s (code: %lu)", (char *)buf, error); + char *buf = php_win32_error_to_msg(error); + size_t buf_len; + + buf_len = strlen(buf); + if (buf_len >= 2) { + buf[buf_len - 1] = '\0'; + buf[buf_len - 2] = '\0'; } + php_error_docref2(NULL, param1, param2, E_WARNING, "%s (code: %lu)", buf, error); + php_win32_error_msg_free(buf); } -#undef PHP_WIN32_ERROR_MSG_BUFFER_SIZE #endif /* {{{ php_html_puts */ diff --git a/main/network.c b/main/network.c index 7eccb36047..94f4a83871 100644 --- a/main/network.c +++ b/main/network.c @@ -28,6 +28,7 @@ #ifdef PHP_WIN32 # include # include "win32/inet.h" +# include "win32/winutil.h" # define O_RDONLY _O_RDONLY # include "win32/param.h" #else @@ -1020,20 +1021,8 @@ PHPAPI char *php_socket_strerror(long err, char *buf, size_t bufsize) } return buf; #else - char *sysbuf; - int free_it = 1; - - if (!FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - err, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPTSTR)&sysbuf, - 0, - NULL)) { - free_it = 0; + char *sysbuf = php_win32_error_to_msg(err); + if (!sysbuf[0]) { sysbuf = "Unknown Error"; } @@ -1044,9 +1033,7 @@ PHPAPI char *php_socket_strerror(long err, char *buf, size_t bufsize) buf[bufsize?(bufsize-1):0] = 0; } - if (free_it) { - LocalFree(sysbuf); - } + php_win32_error_msg_free(sysbuf); return buf; #endif @@ -1063,28 +1050,15 @@ PHPAPI zend_string *php_socket_error_str(long err) return zend_string_init(errstr, strlen(errstr), 0); #else zend_string *ret; - char *sysbuf; - int free_it = 1; - - if (!FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - err, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPTSTR)&sysbuf, - 0, - NULL)) { - free_it = 0; + + char *sysbuf = php_win32_error_to_msg(err); + if (!sysbuf[0]) { sysbuf = "Unknown Error"; } ret = zend_string_init(sysbuf, strlen(sysbuf), 0); - if (free_it) { - LocalFree(sysbuf); - } + php_win32_error_msg_free(sysbuf); return ret; #endif diff --git a/main/php_ini.c b/main/php_ini.c index 24c3cdd5c5..c01eef9851 100644 --- a/main/php_ini.c +++ b/main/php_ini.c @@ -29,6 +29,7 @@ #include "php_scandir.h" #ifdef PHP_WIN32 #include "win32/php_registry.h" +#include "win32/winutil.h" #endif #if HAVE_SCANDIR && HAVE_ALPHASORT && HAVE_DIRENT_H diff --git a/sapi/cgi/cgi_main.c b/sapi/cgi/cgi_main.c index 4041f93789..a4be18aaed 100644 --- a/sapi/cgi/cgi_main.c +++ b/sapi/cgi/cgi_main.c @@ -2149,6 +2149,7 @@ consult the installation file that came with this distribution, or visit \n\ char *err_text = php_win32_error_to_msg(err); fprintf(stderr, "unable to get current command line: [0x%08lx]: %s\n", err, err_text); + php_win32_error_msg_free(err_text); goto parent_out; } @@ -2167,6 +2168,8 @@ consult the installation file that came with this distribution, or visit \n\ fprintf(stderr, "unable to create job object: [0x%08lx]: %s\n", err, err_text); + php_win32_error_msg_free(err_text); + goto parent_out; } @@ -2176,6 +2179,7 @@ consult the installation file that came with this distribution, or visit \n\ char *err_text = php_win32_error_to_msg(err); fprintf(stderr, "unable to configure job object: [0x%08lx]: %s\n", err, err_text); + php_win32_error_msg_free(err_text); } while (parent) { @@ -2216,6 +2220,7 @@ consult the installation file that came with this distribution, or visit \n\ char *err_text = php_win32_error_to_msg(err); fprintf(stderr, "unable to assign child process to job object: [0x%08lx]: %s\n", err, err_text); + php_win32_error_msg_free(err_text); } CloseHandle(pi.hThread); } else { @@ -2225,6 +2230,7 @@ consult the installation file that came with this distribution, or visit \n\ kid_cgi_ps[i] = NULL; fprintf(stderr, "unable to spawn: [0x%08lx]: %s\n", err, err_text); + php_win32_error_msg_free(err_text); } } diff --git a/sapi/phpdbg/phpdbg_prompt.c b/sapi/phpdbg/phpdbg_prompt.c index 8815b90be2..f4b5a11fef 100644 --- a/sapi/phpdbg/phpdbg_prompt.c +++ b/sapi/phpdbg/phpdbg_prompt.c @@ -1311,7 +1311,7 @@ PHPDBG_API const char *phpdbg_load_module_or_extension(char **path, char **name) char *err = GET_DL_ERROR(); if (err && err[0]) { phpdbg_error("dl", "type=\"unknown\"", "%s", err); - LocalFree(err); + php_win32_error_msg_free(err); } else { phpdbg_error("dl", "type=\"unknown\"", "Unknown reason"); } diff --git a/win32/winutil.c b/win32/winutil.c index d719bb6ee5..e44d876d49 100644 --- a/win32/winutil.c +++ b/win32/winutil.c @@ -19,19 +19,36 @@ #include "php.h" #include "winutil.h" +#include "codepage.h" #include #include PHP_WINUTIL_API char *php_win32_error_to_msg(HRESULT error) {/*{{{*/ - char *buf = NULL; + wchar_t *bufw = NULL; + char *buf; - FormatMessage( - FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&buf, 0, NULL + DWORD ret = FormatMessageW( + FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR)&bufw, 0, NULL ); - return (buf ? (char *) buf : ""); + if (!ret || !bufw) { + return ""; + } + + buf = php_win32_cp_conv_w_to_any(bufw, ret, PHP_WIN32_CP_IGNORE_LEN_P); + + LocalFree(bufw); + + return (buf ? buf : ""); +}/*}}}*/ + +PHP_WINUTIL_API void php_win32_error_msg_free(char *msg) +{/*{{{*/ + if (msg && msg[0]) { + free(msg); + } }/*}}}*/ int php_win32_check_trailing_space(const char * path, const size_t path_len) diff --git a/win32/winutil.h b/win32/winutil.h index c08ab5e27e..63837c95a0 100644 --- a/win32/winutil.h +++ b/win32/winutil.h @@ -26,8 +26,10 @@ #endif PHP_WINUTIL_API char *php_win32_error_to_msg(HRESULT error); +PHP_WINUTIL_API void php_win32_error_msg_free(char *msg); #define php_win_err() php_win32_error_to_msg(GetLastError()) +#define php_win_err_free(err) php_win32_error_msg_free(err) int php_win32_check_trailing_space(const char * path, const size_t path_len); PHP_WINUTIL_API int php_win32_get_random_bytes(unsigned char *buf, size_t size); #ifdef PHP_EXPORTS