]> granicus.if.org Git - php/commitdiff
Fix localized error messages and memory leaks
authorAnatol Belski <ab@php.net>
Mon, 17 Sep 2018 07:48:33 +0000 (09:48 +0200)
committerAnatol Belski <ab@php.net>
Mon, 17 Sep 2018 08:56:50 +0000 (10:56 +0200)
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

20 files changed:
Zend/zend_alloc.c
ext/com_dotnet/com_com.c
ext/com_dotnet/com_dotnet.c
ext/com_dotnet/com_misc.c
ext/com_dotnet/com_olechar.c
ext/com_dotnet/com_variant.c
ext/opcache/shared_alloc_win32.c
ext/openssl/xp_ssl.c
ext/sockets/sockets.c
ext/standard/dl.c
ext/standard/exec.c
ext/standard/filestat.c
ext/standard/var_unserializer.c
main/main.c
main/network.c
main/php_ini.c
sapi/cgi/cgi_main.c
sapi/phpdbg/phpdbg_prompt.c
win32/winutil.c
win32/winutil.h

index c1250d1e786de3a0af6c84f73eb53be4cab108fe..d3b24612018758fd2f7337922c58b322d03e2cba 100644 (file)
@@ -68,6 +68,7 @@
 #ifdef ZEND_WIN32
 # include <wincrypt.h>
 # include <process.h>
+# include "win32/winutil.h"
 #endif
 
 #include <stdio.h>
@@ -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
 
index eb79ed76ff07e08bcb7a1f6c361d40df886f9406..5ddf3358c54a7ecce9c06fe2c26a1a5870009b28 100644 (file)
@@ -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;
index f8bdefdf2156f93c7e5df3893130ef6138cd3670..f52243636589bc5e5302dd1d61550f103beb6903 100644 (file)
@@ -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;
        }
index 6488b3c8b44323084b3662752824e496e6dca526..c534117f9d8a1d9fdd42bc477cd1c259d310928c 100644 (file)
@@ -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);
        }
 }
 
index b9a332e4f54421abd66ef9739289ead423c3e5bd..c586756ad726911009bcb176def001ffb854c20e 100644 (file)
@@ -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) {
index 170f15b6e725b311d8f15a01df3b6d4b7b0ec53f..e2b515caad6d0eb619a0161197dc6f47824d1f3b 100644 (file)
@@ -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);
index 5207a5981273c83ca2dda6c79f7012b9d10aa5e4..917975584957ade7fc32fb92cfb3e309756856d1 100644 (file)
@@ -23,6 +23,7 @@
 #include "zend_shared_alloc.h"
 #include "zend_accelerator_util_funcs.h"
 #include "tsrm_win32.h"
+#include "win32/winutil.h"
 #include <winbase.h>
 #include <process.h>
 #include <LMCONS.H>
@@ -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)
index 11bea412953338bdd1c7b76366d552930ca4ea9b..4c4bfaddd3ef98de7597af4cf45e9e6d0e336c1b 100644 (file)
@@ -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);
                }
 
index e8e689f83af4c6c9572195dd7d6c220b14c3ac65..748f2101288cb7e124585b3e1f913d388722a7ee 100644 (file)
@@ -37,6 +37,7 @@
 # include <Ws2tcpip.h>
 # include "php_sockets.h"
 # include <win32/sockets.h>
+# include <win32/winutil.h>
 #else
 # include <sys/types.h>
 # include <sys/socket.h>
@@ -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;
        }
 
index 6b50f22bf47c8fc577661ff8eeb4fe77e28e2486..5ac18f126ff4fa390842f6b74aaa55a8281d4600 100644 (file)
@@ -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("<No message>");
index d914a1fd7262c5f863e5b582c7835f67f81cde04..5b885c554d8cd5bcd25cd1c06d2caa52521c82ce 100644 (file)
@@ -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
index 3a3c024b6aeb3008fcfe1fb8fe99364c48994a5d..6073922f3816718de0e6c8d68723a74c3b687926 100644 (file)
@@ -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;
        }
index 518277ca00ab65b4feb01ece36aaa909e6100e81..3c1c18a700c29054764c490fad4053d4f036de04 100644 (file)
@@ -1,4 +1,4 @@
-/* Generated by re2c 1.0.1 */
+/* Generated by re2c 1.0.3 */
 #line 1 "ext/standard/var_unserializer.re"
 /*
   +----------------------------------------------------------------------+
index c9c05dece5c205bc97e027f41692ff977882b446..e77ec61ca875bbcec5b95266d1f908a7774016dd 100644 (file)
@@ -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 */
index 7eccb36047270d79d4fa1a907a2834cf42dcc444..94f4a83871828d47f20f2d7050d50d0822e99d4a 100644 (file)
@@ -28,6 +28,7 @@
 #ifdef PHP_WIN32
 # include <Ws2tcpip.h>
 # 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
index 24c3cdd5c5715edd7e6a84b051c8a1a5504e33ee..c01eef985171965cc7f4a92f4ac43b67dcfaf1c0 100644 (file)
@@ -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
index 4041f9378999b68feff0c9346a7a9897e2a727ea..a4be18aaed1f12d9a3edf7b149f7cb90e3e21a7d 100644 (file)
@@ -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);
                                        }
                                }
 
index 8815b90be21d9b291bbae095f8ec1ee78e65ff15..f4b5a11fefa88ae9a186d347ebf23989d5699f65 100644 (file)
@@ -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");
                }
index d719bb6ee577f6d9bc7e76dbf8f49857867155e1..e44d876d495d2985a14408873cbe6f666e4df509 100644 (file)
 
 #include "php.h"
 #include "winutil.h"
+#include "codepage.h"
 #include <bcrypt.h>
 #include <lmcons.h>
 
 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)
index c08ab5e27eeacc6b3d98897165ac57a00e36ff8f..63837c95a034799e4cd335fd95f4ef3735e895b5 100644 (file)
 #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