1
0
Fork 0

Added dprintf_args_untranslated_html which will add unescpated HTML to LogView

This commit is contained in:
Josh Brown 2022-05-27 18:36:45 -07:00
parent d32d44258f
commit b9e503d8ef
10 changed files with 94 additions and 23 deletions

View File

@ -1130,6 +1130,11 @@ BRIDGE_IMPEXP void GuiAddLogMessage(const char* msg)
_gui_sendmessage(GUI_ADD_MSG_TO_LOG, (void*)msg, 0);
}
BRIDGE_IMPEXP void GuiAddLogMessageHtml(const char* msg)
{
_gui_sendmessage(GUI_ADD_MSG_TO_LOG_HTML, (void*)msg, 0);
}
BRIDGE_IMPEXP void GuiLogClear()
{
_gui_sendmessage(GUI_CLEAR_LOG, 0, 0);

View File

@ -1089,6 +1089,7 @@ typedef enum
GUI_DISASSEMBLE_AT, // param1=(duint)va, param2=(duint)cip
GUI_SET_DEBUG_STATE, // param1=(DBGSTATE)state, param2=unused
GUI_ADD_MSG_TO_LOG, // param1=(const char*)msg, param2=unused
GUI_ADD_MSG_TO_LOG_HTML, // param1=(const char*)msg, param2=unused
GUI_CLEAR_LOG, // param1=unused, param2=unused
GUI_UPDATE_REGISTER_VIEW, // param1=unused, param2=unused
GUI_UPDATE_DISASSEMBLY_VIEW, // param1=unused, param2=unused
@ -1265,6 +1266,7 @@ BRIDGE_IMPEXP void GuiDisasmAt(duint addr, duint cip);
BRIDGE_IMPEXP void GuiSetDebugState(DBGSTATE state);
BRIDGE_IMPEXP void GuiSetDebugStateFast(DBGSTATE state);
BRIDGE_IMPEXP void GuiAddLogMessage(const char* msg);
BRIDGE_IMPEXP void GuiAddLogMessageHtml(const char* msg);
BRIDGE_IMPEXP void GuiLogClear();
BRIDGE_IMPEXP void GuiUpdateAllViews();
BRIDGE_IMPEXP void GuiUpdateRegisterView();

View File

@ -41,6 +41,15 @@ PLUG_IMPEXP void _plugin_logprintf(const char* format, ...)
va_end(args);
}
PLUG_IMPEXP void _plugin_logprintf_html(const char* format, ...)
{
va_list args;
va_start(args, format);
dprintf_args_untranslated_html(format, args);
va_end(args);
}
PLUG_IMPEXP void _plugin_logputs(const char* text)
{
dputs_untranslated(text);

View File

@ -322,6 +322,7 @@ PLUG_IMPEXP bool _plugin_unregistercallback(int pluginHandle, CBTYPE cbType);
PLUG_IMPEXP bool _plugin_registercommand(int pluginHandle, const char* command, CBPLUGINCOMMAND cbCommand, bool debugonly);
PLUG_IMPEXP bool _plugin_unregistercommand(int pluginHandle, const char* command);
PLUG_IMPEXP void _plugin_logprintf(const char* format, ...);
PLUG_IMPEXP void _plugin_logprintf_html(const char* format, ...);
PLUG_IMPEXP void _plugin_logputs(const char* text);
PLUG_IMPEXP void _plugin_logprint(const char* text);
PLUG_IMPEXP void _plugin_debugpause();

View File

@ -15,6 +15,15 @@ static void GuiAddLogMessageAsync(_In_z_ const char* msg)
task.WakeUp(msg);
}
static void GuiAddLogMessageHtmlAsync(_In_z_ const char* msg)
{
static StringConcatTaskThread_<void(*)(const std::string &)> task([](const std::string & msg)
{
GuiAddLogMessageHtml(msg.c_str());
});
task.WakeUp(msg);
}
/**
\brief Print a line with text, terminated with a newline to the console.
\param text The text to print.
@ -102,3 +111,15 @@ void dprintf_args_untranslated(_In_z_ _Printf_format_string_ const char* Format,
GuiAddLogMessageAsync(buffer);
}
/**
\brief Print a html formatted string to the console.
\param format The printf format to use (see documentation of printf for more information).
\param Args The argument buffer passed to the string parser.
*/
void dprintf_args_untranslated_html(_In_z_ _Printf_format_string_ const char* Format, va_list Args)
{
char buffer[16384];
vsnprintf_s(buffer, _TRUNCATE, Format, Args);
GuiAddLogMessageHtmlAsync(buffer);
}

View File

@ -9,5 +9,6 @@ void dprintf_args(_In_z_ _Printf_format_string_ const char* Format, va_list Args
void dputs_untranslated(_In_z_ const char* Text);
void dprintf_untranslated(_In_z_ _Printf_format_string_ const char* Format, ...);
void dprintf_args_untranslated(_In_z_ _Printf_format_string_ const char* Format, va_list Args);
void dprintf_args_untranslated_html(_In_z_ _Printf_format_string_ const char* Format, va_list Args);
#endif // _CONSOLE_H

View File

@ -116,6 +116,13 @@ void* Bridge::processMessage(GUIMSG type, void* param1, void* param2)
}
break;
case GUI_ADD_MSG_TO_LOG_HTML:
{
auto msg = (const char*)param1;
emit addMsgToLogHtml(QByteArray(msg, int(strlen(msg)) + 1)); //Speed up performance: don't convert to UCS-2 QString
}
break;
case GUI_CLEAR_LOG:
emit clearLog();
break;

View File

@ -50,6 +50,7 @@ signals:
void updateDisassembly();
void dbgStateChanged(DBGSTATE state);
void addMsgToLog(QByteArray msg);
void addMsgToLogHtml(QByteArray msg);
void clearLog();
void close();
void updateRegisters();

View File

@ -36,6 +36,7 @@ LogView::LogView(QWidget* parent) : QTextBrowser(parent), logRedirection(NULL)
connect(Config(), SIGNAL(colorsUpdated()), this, SLOT(updateStyle()));
connect(Config(), SIGNAL(fontsUpdated()), this, SLOT(updateStyle()));
connect(Bridge::getBridge(), SIGNAL(addMsgToLog(QByteArray)), this, SLOT(addMsgToLogSlot(QByteArray)));
connect(Bridge::getBridge(), SIGNAL(addMsgToLogHtml(QByteArray)), this, SLOT(addMsgToLogSlotHtml(QByteArray)));
connect(Bridge::getBridge(), SIGNAL(clearLog()), this, SLOT(clearLogSlot()));
connect(Bridge::getBridge(), SIGNAL(setLogEnabled(bool)), this, SLOT(setLoggingEnabled(bool)));
connect(Bridge::getBridge(), SIGNAL(flushLog()), this, SLOT(flushLogSlot()));
@ -180,29 +181,36 @@ static void linkify(QString & msg)
}
/**
* @brief Color message where applicable via HTML.
* @param msg The message passed by reference.
* @brief LogView::addMsgToLogSlotHtml Adds a HTML message to the log view. This function is a slot for Bridge::addMsgToLogHtml.
* @param msg The log message (Which is assumed to contain HTML)
*/
static QRegularExpression colourRegExp("\\[color@([#0-9A-Za-z]+)\\]");
static QRegularExpression colourEndRegExp("\\[stopcolor\\]");
static void colorize(QString & msg)
void LogView::addMsgToLogSlotHtml(QByteArray msg)
{
msg.replace(colourRegExp, "<span style=\"color:\\1;\">");
msg.replace(colourEndRegExp, "</span>");
LogView::addMsgToLogSlotRaw(msg, false);
}
/**
* @brief LogView::addMsgToLogSlot Adds a message to the log view. This function is a slot for Bridge::addMsgToLog.
* @param msg The log message
*/
* @brief LogView::addMsgToLogSlot Adds a message to the log view. This function is a slot for Bridge::addMsgToLog.
* @param msg The log message
*/
void LogView::addMsgToLogSlot(QByteArray msg)
{
LogView::addMsgToLogSlotRaw(msg, true);
}
/**
* @brief LogView::addMsgToLogSlotRaw Adds a message to the log view.
* @param msg The log message
* @param encodeHTML HTML-encode the log message or not
*/
void LogView::addMsgToLogSlotRaw(QByteArray msg, bool encodeHTML)
{
/*
* This supports the 'UTF-8 Everywhere' manifesto.
* - UTF-8 (http://utf8everywhere.org);
* - No BOM (http://utf8everywhere.org/#faq.boms);
* - No carriage return (http://utf8everywhere.org/#faq.crlf).
*/
* This supports the 'UTF-8 Everywhere' manifesto.
* - UTF-8 (http://utf8everywhere.org);
* - No BOM (http://utf8everywhere.org/#faq.boms);
* - No carriage return (http://utf8everywhere.org/#faq.crlf).
*/
// fix Unix-style line endings.
// redirect the log
@ -227,7 +235,7 @@ void LogView::addMsgToLogSlot(QByteArray msg)
std::string temp;
size_t offset = 0;
size_t buffersize = 0;
if(strstr(msg.constData(), "\r\n") != nullptr) // Don't replace "\r\n" to "\n" if there is none
if(strstr(msg.constData(), "\r\n") != nullptr) // Don't replace "\r\n" to "\n" if there is none
{
temp = msg.constData();
while(true)
@ -256,12 +264,20 @@ void LogView::addMsgToLogSlot(QByteArray msg)
msgUtf16 = QString::fromUtf8(data, int(buffersize));
}
}
else
msgUtf16 = QString::fromUtf8(msg);
else msgUtf16 = QString::fromUtf8(msg);
if(!loggingEnabled)
return;
msgUtf16 = msgUtf16.toHtmlEscaped();
msgUtf16.replace(QChar(' '), QString("&nbsp;"));
if(encodeHTML)
{
msgUtf16 = msgUtf16.toHtmlEscaped();
/* Below line will break HTML tags with spaces separating the HTML tag name and attributes.
ie <a href="aaaa"> -> <a&nbsp;href="aaaa">
so we don't escape spaces where we deliberately passed in HTML.
*/
msgUtf16.replace(QChar(' '), QString("&nbsp;"));
}
if(logRedirection)
{
if(utf16Redirect)
@ -274,8 +290,13 @@ void LogView::addMsgToLogSlot(QByteArray msg)
msgUtf16.replace(QChar('\n'), QString("<br/>\n"));
msgUtf16.replace(QString("\r\n"), QString("<br/>\n"));
}
linkify(msgUtf16);
colorize(msgUtf16);
if(encodeHTML)
{
/* If we passed in non-html log string, we look for address links.
* otherwise, if our HTML contains any address-looking word, ie in our CSS, it would be mangled
* linking to addresses when passing in HTML log message is an exercise left to the plugin developer */
linkify(msgUtf16);
}
if(redirectError)
msgUtf16.append(tr("fwrite() failed (GetLastError()= %1 ). Log redirection stopped.\n").arg(GetLastError()));

View File

@ -17,7 +17,8 @@ public:
public slots:
void refreshShortcutsSlot();
void updateStyle();
void addMsgToLogSlot(QByteArray msg);
void addMsgToLogSlot(QByteArray msg); /* Non-HTML Log Function*/
void addMsgToLogSlotHtml(QByteArray msg); /* HTML accepting Log Function */
void redirectLogSlot();
void setLoggingEnabled(bool enabled);
void autoScrollSlot();
@ -36,6 +37,8 @@ public slots:
private:
static const int MAX_LOG_BUFFER_SIZE = 1024 * 1024;
void addMsgToLogSlotRaw(QByteArray msg, bool htmlEscape); /* Non-HTML Log Function*/
bool loggingEnabled;
bool autoScroll;
bool utf16Redirect = false;