mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-08-26 10:58:53 +02:00
Add specific test for private functions
This commit is contained in:
@@ -1,80 +0,0 @@
|
||||
/* gwin32-private.c - private glib functions for gwin32.c
|
||||
*
|
||||
* Copyright 2019 Руслан Ижбулатов
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* Copy @cmdline into @debugger, and substitute @pid for `%p`
|
||||
* and @event for `%e`.
|
||||
* If @debugger_size (in wchar_ts) is overflowed, return %FALSE.
|
||||
* Also returns %FALSE when `%` is followed by anything other
|
||||
* than `e` or `p`.
|
||||
*/
|
||||
static gboolean
|
||||
_g_win32_subst_pid_and_event_w (wchar_t *local_debugger,
|
||||
gsize debugger_size,
|
||||
const wchar_t *cmdline,
|
||||
DWORD pid,
|
||||
guintptr event)
|
||||
{
|
||||
gsize i = 0, dbg_i = 0;
|
||||
/* These are integers, and they can't be longer than 20 characters
|
||||
* even when they are 64-bit and in decimal notation.
|
||||
* Use 30 just to be sure.
|
||||
*/
|
||||
#define STR_BUFFER_SIZE 30
|
||||
wchar_t pid_str[STR_BUFFER_SIZE] = {0};
|
||||
gsize pid_str_len;
|
||||
wchar_t event_str[STR_BUFFER_SIZE] = {0};
|
||||
gsize event_str_len;
|
||||
|
||||
_snwprintf_s (pid_str, STR_BUFFER_SIZE, G_N_ELEMENTS (pid_str), L"%lu", pid);
|
||||
pid_str[G_N_ELEMENTS (pid_str) - 1] = 0;
|
||||
pid_str_len = wcslen (pid_str);
|
||||
_snwprintf_s (event_str, STR_BUFFER_SIZE, G_N_ELEMENTS (pid_str), L"%Iu", event);
|
||||
event_str[G_N_ELEMENTS (pid_str) - 1] = 0;
|
||||
event_str_len = wcslen (event_str);
|
||||
#undef STR_BUFFER_SIZE
|
||||
|
||||
while (cmdline[i] != 0 && dbg_i < debugger_size)
|
||||
{
|
||||
if (cmdline[i] != L'%')
|
||||
local_debugger[dbg_i++] = cmdline[i++];
|
||||
else if (cmdline[i + 1] == L'p')
|
||||
{
|
||||
gsize j = 0;
|
||||
while (j < pid_str_len && dbg_i < debugger_size)
|
||||
local_debugger[dbg_i++] = pid_str[j++];
|
||||
i += 2;
|
||||
}
|
||||
else if (cmdline[i + 1] == L'e')
|
||||
{
|
||||
gsize j = 0;
|
||||
while (j < event_str_len && dbg_i < debugger_size)
|
||||
local_debugger[dbg_i++] = event_str[j++];
|
||||
i += 2;
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
if (dbg_i < debugger_size)
|
||||
local_debugger[dbg_i] = 0;
|
||||
else
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
@@ -70,6 +70,8 @@
|
||||
#endif
|
||||
|
||||
#include "glib.h"
|
||||
#include "gwin32.h"
|
||||
#include "gwin32private.h"
|
||||
#include "gthreadprivate.h"
|
||||
#include "glib-init.h"
|
||||
|
||||
@@ -1065,7 +1067,66 @@ static DWORD *exceptions_to_catch = NULL;
|
||||
static HANDLE debugger_wakeup_event = 0;
|
||||
static DWORD debugger_spawn_flags = 0;
|
||||
|
||||
#include "gwin32-private.c"
|
||||
/* Copy @cmdline into @debugger, and substitute @pid for `%p`
|
||||
* and @event for `%e`.
|
||||
* If @debugger_size (in wchar_ts) is overflowed, return %FALSE.
|
||||
* Also returns %FALSE when `%` is followed by anything other
|
||||
* than `e` or `p`.
|
||||
*/
|
||||
bool
|
||||
g_win32_substitute_pid_and_event (wchar_t *local_debugger,
|
||||
gsize debugger_size,
|
||||
const wchar_t *cmdline,
|
||||
DWORD pid,
|
||||
guintptr event)
|
||||
{
|
||||
gsize i = 0, dbg_i = 0;
|
||||
/* These are integers, and they can't be longer than 20 characters
|
||||
* even when they are 64-bit and in decimal notation.
|
||||
* Use 30 just to be sure.
|
||||
*/
|
||||
#define STR_BUFFER_SIZE 30
|
||||
wchar_t pid_str[STR_BUFFER_SIZE] = {0};
|
||||
gsize pid_str_len;
|
||||
wchar_t event_str[STR_BUFFER_SIZE] = {0};
|
||||
gsize event_str_len;
|
||||
|
||||
_snwprintf_s (pid_str, STR_BUFFER_SIZE, G_N_ELEMENTS (pid_str), L"%lu", pid);
|
||||
pid_str[G_N_ELEMENTS (pid_str) - 1] = 0;
|
||||
pid_str_len = wcslen (pid_str);
|
||||
_snwprintf_s (event_str, STR_BUFFER_SIZE, G_N_ELEMENTS (pid_str), L"%Iu", event);
|
||||
event_str[G_N_ELEMENTS (pid_str) - 1] = 0;
|
||||
event_str_len = wcslen (event_str);
|
||||
#undef STR_BUFFER_SIZE
|
||||
|
||||
while (cmdline[i] != 0 && dbg_i < debugger_size)
|
||||
{
|
||||
if (cmdline[i] != L'%')
|
||||
local_debugger[dbg_i++] = cmdline[i++];
|
||||
else if (cmdline[i + 1] == L'p')
|
||||
{
|
||||
gsize j = 0;
|
||||
while (j < pid_str_len && dbg_i < debugger_size)
|
||||
local_debugger[dbg_i++] = pid_str[j++];
|
||||
i += 2;
|
||||
}
|
||||
else if (cmdline[i + 1] == L'e')
|
||||
{
|
||||
gsize j = 0;
|
||||
while (j < event_str_len && dbg_i < debugger_size)
|
||||
local_debugger[dbg_i++] = event_str[j++];
|
||||
i += 2;
|
||||
}
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
if (dbg_i < debugger_size)
|
||||
local_debugger[dbg_i] = 0;
|
||||
else
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static char *
|
||||
copy_chars (char *buffer,
|
||||
@@ -1295,9 +1356,9 @@ g_crash_handler_win32_init (void)
|
||||
debugger_wakeup_event = CreateEvent (&sa, FALSE, FALSE, NULL);
|
||||
|
||||
/* Put process ID and event handle into debugger commandline */
|
||||
if (!_g_win32_subst_pid_and_event_w (debugger, G_N_ELEMENTS (debugger),
|
||||
debugger_env, GetCurrentProcessId (),
|
||||
(guintptr) debugger_wakeup_event))
|
||||
if (!g_win32_substitute_pid_and_event (debugger, G_N_ELEMENTS (debugger),
|
||||
debugger_env, GetCurrentProcessId (),
|
||||
(guintptr) debugger_wakeup_event))
|
||||
{
|
||||
CloseHandle (debugger_wakeup_event);
|
||||
debugger_wakeup_event = 0;
|
||||
|
42
glib/gwin32private.h
Normal file
42
glib/gwin32private.h
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright © 2025 Luca Bacci
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Author: Luca Bacci <luca.bacci@outlook.com>
|
||||
*/
|
||||
|
||||
#ifndef __G_WIN32PRIVATE_H__
|
||||
#define __G_WIN32PRIVATE_H__
|
||||
|
||||
#ifdef G_PLATFORM_WIN32
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <windows.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
bool
|
||||
g_win32_substitute_pid_and_event (wchar_t *local_debugger,
|
||||
gsize debugger_size,
|
||||
const wchar_t *cmdline,
|
||||
DWORD pid,
|
||||
guintptr event);
|
||||
|
||||
|
||||
#endif /* G_PLATFORM_WIN32 */
|
||||
|
||||
#endif /* __G_WIN32PRIVATE_H__ */
|
@@ -251,6 +251,7 @@ if host_machine.system() == 'windows'
|
||||
'win32' : {
|
||||
'dependencies' : [wincodecs],
|
||||
},
|
||||
'win32-private' : {},
|
||||
}
|
||||
else
|
||||
glib_tests += {
|
||||
|
77
glib/tests/win32-private.c
Normal file
77
glib/tests/win32-private.c
Normal file
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright © 2019 Руслан Ижбулатов
|
||||
* Copyright © 2025 Luca Bacci
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib/gwin32private.h>
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
static void
|
||||
test_substitute_pid_and_event (void)
|
||||
{
|
||||
const wchar_t not_enough[] = L"too long when %e and %p are substituted";
|
||||
wchar_t debugger_3[3];
|
||||
wchar_t debugger_not_enough[G_N_ELEMENTS (not_enough)];
|
||||
wchar_t debugger_enough[G_N_ELEMENTS (not_enough) + 1];
|
||||
char *debugger_enough_utf8;
|
||||
wchar_t debugger_big[65535] = {0};
|
||||
char *debugger_big_utf8;
|
||||
gchar *output;
|
||||
guintptr be = (guintptr) 0xFFFFFFFF;
|
||||
DWORD bp = MAXDWORD;
|
||||
|
||||
/* %f is not valid */
|
||||
g_assert_false (g_win32_substitute_pid_and_event (debugger_3, G_N_ELEMENTS (debugger_3),
|
||||
L"%f", 0, 0));
|
||||
|
||||
g_assert_false (g_win32_substitute_pid_and_event (debugger_3, G_N_ELEMENTS (debugger_3),
|
||||
L"string longer than 10", 0, 0));
|
||||
/* 200 is longer than %e, so the string doesn't fit by 1 byte */
|
||||
g_assert_false (g_win32_substitute_pid_and_event (debugger_not_enough, G_N_ELEMENTS (debugger_not_enough),
|
||||
not_enough, 10, 200));
|
||||
|
||||
/* This should fit */
|
||||
g_assert_true (g_win32_substitute_pid_and_event (debugger_enough, G_N_ELEMENTS (debugger_enough),
|
||||
not_enough, 10, 200));
|
||||
debugger_enough_utf8 = g_utf16_to_utf8 (debugger_enough, -1, NULL, NULL, NULL);
|
||||
g_assert_cmpstr (debugger_enough_utf8, ==, "too long when 200 and 10 are substituted");
|
||||
g_free (debugger_enough_utf8);
|
||||
|
||||
g_assert_true (g_win32_substitute_pid_and_event (debugger_big, G_N_ELEMENTS (debugger_big),
|
||||
L"multipl%e big %e %entries and %pids are %provided here", bp, be));
|
||||
debugger_big_utf8 = g_utf16_to_utf8 (debugger_big, -1, NULL, NULL, NULL);
|
||||
output = g_strdup_printf ("multipl%llu big %llu %lluntries and %luids are %lurovided here", (guint64) be, (guint64) be, (guint64) be, bp, bp);
|
||||
g_assert_cmpstr (debugger_big_utf8, ==, output);
|
||||
g_free (debugger_big_utf8);
|
||||
g_free (output);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc,
|
||||
char *argv[])
|
||||
{
|
||||
g_test_init (&argc, &argv, NULL);
|
||||
|
||||
g_test_add_func ("/win32/substitute-pid-and-event", test_substitute_pid_and_event);
|
||||
|
||||
return g_test_run();
|
||||
}
|
@@ -33,48 +33,6 @@
|
||||
|
||||
static char *argv0 = NULL;
|
||||
|
||||
#include "../gwin32-private.c"
|
||||
|
||||
static void
|
||||
test_subst_pid_and_event (void)
|
||||
{
|
||||
const wchar_t not_enough[] = L"too long when %e and %p are substituted";
|
||||
wchar_t debugger_3[3];
|
||||
wchar_t debugger_not_enough[G_N_ELEMENTS (not_enough)];
|
||||
wchar_t debugger_enough[G_N_ELEMENTS (not_enough) + 1];
|
||||
char *debugger_enough_utf8;
|
||||
wchar_t debugger_big[65535] = {0};
|
||||
char *debugger_big_utf8;
|
||||
gchar *output;
|
||||
guintptr be = (guintptr) 0xFFFFFFFF;
|
||||
DWORD bp = MAXDWORD;
|
||||
|
||||
/* %f is not valid */
|
||||
g_assert_false (_g_win32_subst_pid_and_event_w (debugger_3, G_N_ELEMENTS (debugger_3),
|
||||
L"%f", 0, 0));
|
||||
|
||||
g_assert_false (_g_win32_subst_pid_and_event_w (debugger_3, G_N_ELEMENTS (debugger_3),
|
||||
L"string longer than 10", 0, 0));
|
||||
/* 200 is longer than %e, so the string doesn't fit by 1 byte */
|
||||
g_assert_false (_g_win32_subst_pid_and_event_w (debugger_not_enough, G_N_ELEMENTS (debugger_not_enough),
|
||||
not_enough, 10, 200));
|
||||
|
||||
/* This should fit */
|
||||
g_assert_true (_g_win32_subst_pid_and_event_w (debugger_enough, G_N_ELEMENTS (debugger_enough),
|
||||
not_enough, 10, 200));
|
||||
debugger_enough_utf8 = g_utf16_to_utf8 (debugger_enough, -1, NULL, NULL, NULL);
|
||||
g_assert_cmpstr (debugger_enough_utf8, ==, "too long when 200 and 10 are substituted");
|
||||
g_free (debugger_enough_utf8);
|
||||
|
||||
g_assert_true (_g_win32_subst_pid_and_event_w (debugger_big, G_N_ELEMENTS (debugger_big),
|
||||
L"multipl%e big %e %entries and %pids are %provided here", bp, be));
|
||||
debugger_big_utf8 = g_utf16_to_utf8 (debugger_big, -1, NULL, NULL, NULL);
|
||||
output = g_strdup_printf ("multipl%llu big %llu %lluntries and %luids are %lurovided here", (guint64) be, (guint64) be, (guint64) be, bp, bp);
|
||||
g_assert_cmpstr (debugger_big_utf8, ==, output);
|
||||
g_free (debugger_big_utf8);
|
||||
g_free (output);
|
||||
}
|
||||
|
||||
/* Crash with access violation */
|
||||
static void
|
||||
test_access_violation (void)
|
||||
@@ -194,8 +152,6 @@ main (int argc,
|
||||
return 0;
|
||||
}
|
||||
|
||||
g_test_add_func ("/win32/substitute-pid-and-event", test_subst_pid_and_event);
|
||||
|
||||
g_test_add_func ("/win32/veh/access_violation", test_veh_crash_access_violation);
|
||||
g_test_add_func ("/win32/veh/illegal_instruction", test_veh_crash_illegal_instruction);
|
||||
g_test_add_func ("/win32/veh/debug", test_veh_debug);
|
||||
|
Reference in New Issue
Block a user