aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorRobin Haberkorn <robin.haberkorn@googlemail.com>2015-06-23 16:23:25 +0200
committerRobin Haberkorn <robin.haberkorn@googlemail.com>2015-06-24 03:38:16 +0200
commit81a1270a56bf1f6a13e709e653598c69c7d9334b (patch)
tree7411ac19a1c40e3f68bf25697daaf2bb1a5ddc44
parent9e3913e8e9c25916911ef5e9f2a2d5b17e9e8c5c (diff)
downloadsciteco-81a1270a56bf1f6a13e709e653598c69c7d9334b.tar.gz
fixed SEGFAULTs in InterfaceCurses::vmsg()
* both vmsg() and stdio_msg() behave like vprintf() are allowed to leave their `va_list` in an undefined state. * therefore when writing messages to stdio in addition to the message line, we have to copy the argument list. * fixes SEGFAULTs when trying to log any message (but this bug did not manifest on every test system)
-rw-r--r--src/interface-curses.cpp17
-rw-r--r--src/interface.cpp8
2 files changed, 17 insertions, 8 deletions
diff --git a/src/interface-curses.cpp b/src/interface-curses.cpp
index e46af51..c3216ce 100644
--- a/src/interface-curses.cpp
+++ b/src/interface-curses.cpp
@@ -384,20 +384,21 @@ InterfaceCurses::vmsg_impl(MessageType type, const gchar *fmt, va_list ap)
{
attr_t attr;
+ if (!msg_window) { /* batch mode */
+ stdio_vmsg(type, fmt, ap);
+ return;
+ }
+
/*
* On most platforms we can write to stdout/stderr
* even in interactive mode.
*/
#if defined(XCURSES) || defined(PDCURSES_WIN32A) || \
defined(NCURSES_UNIX) || defined(NCURSES_WIN32)
- stdio_vmsg(type, fmt, ap);
- if (!msg_window) /* batch mode */
- return;
-#else
- if (!msg_window) { /* batch mode */
- stdio_vmsg(type, fmt, ap);
- return;
- }
+ va_list aq;
+ va_copy(aq, ap);
+ stdio_vmsg(type, fmt, aq);
+ va_end(aq);
#endif
switch (type) {
diff --git a/src/interface.cpp b/src/interface.cpp
index 41cc93d..0bcdf28 100644
--- a/src/interface.cpp
+++ b/src/interface.cpp
@@ -107,6 +107,14 @@ Interface<InterfaceImpl, ViewImpl>::UndoTokenInfoUpdate<Type>::run(void)
interface.info_update(obj);
}
+/**
+ * Print a message to the appropriate stdio streams.
+ *
+ * This method has similar semantics to `vprintf`, i.e.
+ * it leaves `ap` undefined. Therefore to pass the format
+ * string and arguments to another `vprintf`-like function,
+ * you have to copy the arguments via `va_copy`.
+ */
template <class InterfaceImpl, class ViewImpl>
void
Interface<InterfaceImpl, ViewImpl>::stdio_vmsg(MessageType type, const gchar *fmt, va_list ap)