This fixes a PSPPIRE bug in its message handling (found by inspection). It
makes copies of messages to use later. The file names were not being
copied, so in the meantime it was posible that they would be freed,
yielding a use-after-free error.
Since doing this sensibly required changing the file_name member of
struct msg_locator from "const char *" to "char *", it also touches up
places where this caused new warnings.
#include <language/lexer/lexer.h>
#include <language/prompt.h>
#include <libpspp/assertion.h>
#include <language/lexer/lexer.h>
#include <language/prompt.h>
#include <libpspp/assertion.h>
+#include <libpspp/cast.h>
#include <libpspp/integer-format.h>
#include <libpspp/message.h>
#include <libpspp/str.h>
#include <libpspp/integer-format.h>
#include <libpspp/message.h>
#include <libpspp/str.h>
if (fh_get_referent (fh) != FH_REF_INLINE)
{
struct stat s;
if (fh_get_referent (fh) != FH_REF_INLINE)
{
struct stat s;
- r->where.file_name = fh_get_file_name (fh);
+ r->where.file_name = CONST_CAST (char *, fh_get_file_name (fh));
r->where.line_number = 0;
r->file = fn_open (fh_get_file_name (fh),
fh_get_mode (fh) == FH_MODE_TEXT ? "r" : "rb");
r->where.line_number = 0;
r->file = fn_open (fh_get_file_name (fh),
fh_get_mode (fh) == FH_MODE_TEXT ? "r" : "rb");
struct msg *
msg_dup(const struct msg *m)
{
struct msg *
msg_dup(const struct msg *m)
{
- struct msg *new_msg = xmalloc (sizeof *m);
- *new_msg = *m;
- new_msg->text = xstrdup(m->text);
+ new_msg = xmemdup (m, sizeof *m);
+ if (m->where.file_name != NULL)
+ new_msg->where.file_name = xstrdup (m->where.file_name);
+ new_msg->text = xstrdup (m->text);
+/* Frees a message created by msg_dup().
+
+ (Messages not created by msg_dup(), as well as their where.file_name
+ members, are typically not dynamically allocated, so this function should
+ not be used to destroy them.) */
-msg_destroy(struct msg *m)
+msg_destroy (struct msg *m)
- free(m->text);
- free(m);
+ free (m->where.file_name);
+ free (m->text);
+ free (m);
}
/* Emits M as an error message.
}
/* Emits M as an error message.
/* A file location. */
struct msg_locator
{
/* A file location. */
struct msg_locator
{
- const char *file_name; /* File name. */
- int line_number; /* Line number. */
+ char *file_name; /* File name. */
+ int line_number; /* Line number. */
#include <config.h>
#include <stdlib.h>
#include "msg-locator.h"
#include <config.h>
#include <stdlib.h>
#include "msg-locator.h"
-#include <libpspp/message.h>
#include <libpspp/assertion.h>
#include <libpspp/assertion.h>
+#include <libpspp/cast.h>
+#include <libpspp/message.h>
#include "getl.h"
#include "xalloc.h"
#include "getl.h"
#include "xalloc.h"
- loc->file_name = getl_source_name (ss);
+ loc->file_name = CONST_CAST (char *, getl_source_name (ss));
loc->line_number = getl_source_location (ss);
}
}
loc->line_number = getl_source_location (ss);
}
}