mirror of
https://github.com/holub/mame
synced 2025-04-25 17:56:43 +03:00
Fix #1802 (uninitialised memory read as debugger command history) and clean up a little
This commit is contained in:
parent
c9fb53a812
commit
44eb44996a
@ -16,9 +16,15 @@
|
||||
#include "winutil.h"
|
||||
|
||||
|
||||
// edit box styles
|
||||
#define EDIT_BOX_STYLE WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL
|
||||
#define EDIT_BOX_STYLE_EX 0
|
||||
namespace {
|
||||
|
||||
constexpr DWORD EDIT_BOX_STYLE = WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL;
|
||||
constexpr DWORD EDIT_BOX_STYLE_EX = 0;
|
||||
|
||||
constexpr int MAX_EDIT_STRING = 256;
|
||||
constexpr int HISTORY_LENGTH = 20;
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
|
||||
editwin_info::editwin_info(debugger_windows_interface &debugger, bool is_main_console, LPCSTR title, WNDPROC handler) :
|
||||
@ -26,7 +32,7 @@ editwin_info::editwin_info(debugger_windows_interface &debugger, bool is_main_co
|
||||
m_editwnd(nullptr),
|
||||
m_edit_defstr(),
|
||||
m_original_editproc(nullptr),
|
||||
m_history_count(0),
|
||||
m_history(),
|
||||
m_last_history(0)
|
||||
{
|
||||
if (window() == nullptr)
|
||||
@ -35,11 +41,11 @@ editwin_info::editwin_info(debugger_windows_interface &debugger, bool is_main_co
|
||||
// create an edit box and override its key handling
|
||||
m_editwnd = CreateWindowEx(EDIT_BOX_STYLE_EX, TEXT("EDIT"), nullptr, EDIT_BOX_STYLE,
|
||||
0, 0, 100, 100, window(), nullptr, GetModuleHandleUni(), nullptr);
|
||||
m_original_editproc = (WNDPROC)(uintptr_t)GetWindowLongPtr(m_editwnd, GWLP_WNDPROC);
|
||||
SetWindowLongPtr(m_editwnd, GWLP_USERDATA, (LONG_PTR)this);
|
||||
SetWindowLongPtr(m_editwnd, GWLP_WNDPROC, (LONG_PTR)&editwin_info::static_edit_proc);
|
||||
SendMessage(m_editwnd, WM_SETFONT, (WPARAM)metrics().debug_font(), (LPARAM)FALSE);
|
||||
SendMessage(m_editwnd, EM_LIMITTEXT, (WPARAM)MAX_EDIT_STRING, (LPARAM)0);
|
||||
m_original_editproc = WNDPROC(uintptr_t(GetWindowLongPtr(m_editwnd, GWLP_WNDPROC)));
|
||||
SetWindowLongPtr(m_editwnd, GWLP_USERDATA, LONG_PTR(this));
|
||||
SetWindowLongPtr(m_editwnd, GWLP_WNDPROC, LONG_PTR(&editwin_info::static_edit_proc));
|
||||
SendMessage(m_editwnd, WM_SETFONT, WPARAM(metrics().debug_font()), LPARAM(FALSE));
|
||||
SendMessage(m_editwnd, EM_LIMITTEXT, WPARAM(MAX_EDIT_STRING), LPARAM(0));
|
||||
set_editwnd_text("");
|
||||
}
|
||||
|
||||
@ -80,13 +86,13 @@ void editwin_info::set_editwnd_bounds(RECT const &bounds)
|
||||
void editwin_info::set_editwnd_text(char const *text)
|
||||
{
|
||||
auto tc_buffer = osd::text::to_tstring(text);
|
||||
SendMessage(m_editwnd, WM_SETTEXT, (WPARAM)0, (LPARAM)tc_buffer.c_str());
|
||||
SendMessage(m_editwnd, WM_SETTEXT, WPARAM(0), LPARAM(tc_buffer.c_str()));
|
||||
}
|
||||
|
||||
|
||||
void editwin_info::editwnd_select_all()
|
||||
{
|
||||
SendMessage(m_editwnd, EM_SETSEL, (WPARAM)0, (LPARAM)-1);
|
||||
SendMessage(m_editwnd, EM_SETSEL, WPARAM(0), LPARAM(-1));
|
||||
}
|
||||
|
||||
|
||||
@ -100,8 +106,6 @@ void editwin_info::draw_contents(HDC dc)
|
||||
|
||||
LRESULT editwin_info::edit_proc(UINT message, WPARAM wparam, LPARAM lparam)
|
||||
{
|
||||
TCHAR buffer[MAX_EDIT_STRING];
|
||||
|
||||
// handle a few messages
|
||||
switch (message)
|
||||
{
|
||||
@ -114,23 +118,28 @@ LRESULT editwin_info::edit_proc(UINT message, WPARAM wparam, LPARAM lparam)
|
||||
switch (wparam)
|
||||
{
|
||||
case VK_UP:
|
||||
if (m_last_history < (m_history_count - 1))
|
||||
if (!m_history.empty())
|
||||
{
|
||||
m_last_history++;
|
||||
else
|
||||
m_last_history = 0;
|
||||
SendMessage(m_editwnd, WM_SETTEXT, (WPARAM)0, (LPARAM)&m_history[m_last_history][0]);
|
||||
SendMessage(m_editwnd, EM_SETSEL, (WPARAM)MAX_EDIT_STRING, (LPARAM)MAX_EDIT_STRING);
|
||||
if (m_last_history >= m_history.size())
|
||||
m_last_history = 0;
|
||||
auto const &entry(m_history[m_last_history]);
|
||||
SendMessage(m_editwnd, WM_SETTEXT, WPARAM(0), LPARAM(entry.c_str()));
|
||||
SendMessage(m_editwnd, EM_SETSEL, WPARAM(entry.length()), LPARAM(entry.length()));
|
||||
}
|
||||
break;
|
||||
|
||||
case VK_DOWN:
|
||||
if (m_last_history > 0)
|
||||
m_last_history--;
|
||||
else if (m_history_count > 0)
|
||||
m_last_history = m_history_count - 1;
|
||||
else
|
||||
m_last_history = 0;
|
||||
SendMessage(m_editwnd, WM_SETTEXT, (WPARAM)0, (LPARAM)&m_history[m_last_history][0]);
|
||||
SendMessage(m_editwnd, EM_SETSEL, (WPARAM)MAX_EDIT_STRING, (LPARAM)MAX_EDIT_STRING);
|
||||
if (!m_history.empty())
|
||||
{
|
||||
if (m_last_history > 0)
|
||||
m_last_history--;
|
||||
else
|
||||
m_last_history = m_history.size() - 1;
|
||||
auto const &entry(m_history[m_last_history]);
|
||||
SendMessage(m_editwnd, WM_SETTEXT, WPARAM(0), LPARAM(entry.c_str()));
|
||||
SendMessage(m_editwnd, EM_SETSEL, WPARAM(entry.length()), LPARAM(entry.length()));
|
||||
}
|
||||
break;
|
||||
|
||||
case VK_PRIOR:
|
||||
@ -168,35 +177,36 @@ LRESULT editwin_info::edit_proc(UINT message, WPARAM wparam, LPARAM lparam)
|
||||
{
|
||||
if (waiting_for_debugger() || !seq_pressed())
|
||||
{
|
||||
TCHAR buffer[MAX_EDIT_STRING];
|
||||
|
||||
switch (wparam)
|
||||
{
|
||||
case 13:
|
||||
case 13: // carriage return
|
||||
{
|
||||
// fetch the text
|
||||
SendMessage(m_editwnd, WM_GETTEXT, (WPARAM)ARRAY_LENGTH(buffer), (LPARAM)buffer);
|
||||
SendMessage(m_editwnd, WM_GETTEXT, WPARAM(ARRAY_LENGTH(buffer)), LPARAM(buffer));
|
||||
|
||||
// add to the history if it's not a repeat of the last one
|
||||
if (buffer[0] != 0 && _tcscmp(buffer, &m_history[0][0]))
|
||||
if (buffer[0] && (m_history.empty() || _tcscmp(buffer, m_history[0].c_str())))
|
||||
{
|
||||
memmove(&m_history[1][0], &m_history[0][0], (HISTORY_LENGTH - 1) * MAX_EDIT_STRING * sizeof(TCHAR));
|
||||
_tcscpy(&m_history[0][0], buffer);
|
||||
if (m_history_count < HISTORY_LENGTH)
|
||||
m_history_count++;
|
||||
while (m_history.size() >= HISTORY_LENGTH)
|
||||
m_history.pop_back();
|
||||
m_history.emplace_front(buffer);
|
||||
}
|
||||
m_last_history = m_history_count - 1;
|
||||
m_last_history = m_history.size() - 1;
|
||||
|
||||
// process
|
||||
{
|
||||
auto utf8_buffer = osd::text::from_tstring(buffer);
|
||||
process_string(utf8_buffer.c_str());
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 27:
|
||||
case 27: // escape
|
||||
{
|
||||
// fetch the text
|
||||
SendMessage(m_editwnd, WM_GETTEXT, (WPARAM)sizeof(buffer), (LPARAM)buffer);
|
||||
SendMessage(m_editwnd, WM_GETTEXT, WPARAM(sizeof(buffer)), LPARAM(buffer));
|
||||
|
||||
// if it's not empty, clear the text
|
||||
if (_tcslen(buffer) > 0)
|
||||
@ -205,8 +215,8 @@ LRESULT editwin_info::edit_proc(UINT message, WPARAM wparam, LPARAM lparam)
|
||||
set_editwnd_text(m_edit_defstr.c_str());
|
||||
editwnd_select_all();
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
return CallWindowProc(m_original_editproc, m_editwnd, message, wparam, lparam);
|
||||
@ -226,7 +236,7 @@ LRESULT editwin_info::edit_proc(UINT message, WPARAM wparam, LPARAM lparam)
|
||||
|
||||
LRESULT CALLBACK editwin_info::static_edit_proc(HWND wnd, UINT message, WPARAM wparam, LPARAM lparam)
|
||||
{
|
||||
editwin_info *const info = (editwin_info *)(uintptr_t)GetWindowLongPtr(wnd, GWLP_USERDATA);
|
||||
editwin_info *const info = (editwin_info *)uintptr_t(GetWindowLongPtr(wnd, GWLP_USERDATA));
|
||||
assert(info->m_editwnd == wnd);
|
||||
return info->edit_proc(message, wparam, lparam);
|
||||
}
|
||||
|
@ -6,13 +6,16 @@
|
||||
//
|
||||
//============================================================
|
||||
|
||||
#ifndef __DEBUG_WIN_EDIT_WIN_INFO_H__
|
||||
#define __DEBUG_WIN_EDIT_WIN_INFO_H__
|
||||
#ifndef MAME_DEBUG_WIN_EDIT_WIN_INFO_H
|
||||
#define MAME_DEBUG_WIN_EDIT_WIN_INFO_H
|
||||
|
||||
#include "debugwin.h"
|
||||
|
||||
#include "debugwininfo.h"
|
||||
|
||||
#include <deque>
|
||||
#include <string>
|
||||
|
||||
|
||||
class editwin_info : public debugwin_info
|
||||
{
|
||||
@ -25,8 +28,8 @@ public:
|
||||
virtual bool set_default_focus() override;
|
||||
|
||||
protected:
|
||||
static DWORD const COMBO_BOX_STYLE = WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST | WS_VSCROLL;
|
||||
static DWORD const COMBO_BOX_STYLE_EX = 0;
|
||||
constexpr static DWORD COMBO_BOX_STYLE = WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST | WS_VSCROLL;
|
||||
constexpr static DWORD COMBO_BOX_STYLE_EX = 0;
|
||||
|
||||
void set_editwnd_bounds(RECT const &bounds);
|
||||
void set_editwnd_text(char const *text);
|
||||
@ -36,21 +39,19 @@ protected:
|
||||
virtual void draw_contents(HDC dc) override;
|
||||
|
||||
private:
|
||||
typedef std::deque<std::basic_string<TCHAR> > history_deque;
|
||||
|
||||
virtual void process_string(char const *string) = 0;
|
||||
|
||||
LRESULT edit_proc(UINT message, WPARAM wparam, LPARAM lparam);
|
||||
|
||||
static LRESULT CALLBACK static_edit_proc(HWND wnd, UINT message, WPARAM wparam, LPARAM lparam);
|
||||
|
||||
static int const MAX_EDIT_STRING = 256;
|
||||
static int const HISTORY_LENGTH = 20;
|
||||
|
||||
HWND m_editwnd;
|
||||
std::string m_edit_defstr;
|
||||
WNDPROC m_original_editproc;
|
||||
TCHAR m_history[HISTORY_LENGTH][MAX_EDIT_STRING];
|
||||
int m_history_count;
|
||||
int m_last_history;
|
||||
HWND m_editwnd;
|
||||
std::string m_edit_defstr;
|
||||
WNDPROC m_original_editproc;
|
||||
history_deque m_history;
|
||||
int m_last_history;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user