/*
* Claws Mail -- a GTK+ based, lightweight, and fast e-mail client
- * Copyright (C) 1999-2016 Hiroyuki Yamamoto & The Claws Mail Team
+ * Copyright (C) 1999-2020 The Claws Mail Team and Hiroyuki Yamamoto
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
return str;
}
+#ifndef HAVE_STRCASESTR
/* Similar to `strstr' but this function ignores the case of both strings. */
gchar *strcasestr(const gchar *haystack, const gchar *needle)
{
return strncasestr(haystack, haystack_len, needle);
}
+#endif /* HAVE_STRCASESTR */
gchar *strncasestr(const gchar *haystack, gint haystack_len, const gchar *needle)
{
len = g_unichar_to_utf8(c, NULL);
- if (!g_unichar_isdefined(c) || !g_unichar_isprint(c) ||
- g_unichar_isspace(c)) {
+ if ((!g_unichar_isdefined(c) || !g_unichar_isprint(c) ||
+ g_unichar_isspace(c)) && c != 173) {
/* replace anything bad or whitespacey with a single space */
*ch = ' ';
ch++;
"../",
NULL };
gint num_attach = 0;
- gchar **my_att = NULL;
+
+ cm_return_val_if_fail(mailto != NULL, -1);
Xstrdup_a(tmp_mailto, mailto, return -1);
if (to && !*to)
*to = decode_uri_gdup(tmp_mailto);
- my_att = g_malloc(sizeof(char *));
- my_att[0] = NULL;
-
while (p) {
gchar *field, *value;
} else {
gchar *tmp = decode_uri_gdup(value);
gchar *new_from = g_strdup_printf("%s, %s", *from, tmp);
+ g_free(tmp);
g_free(*from);
*from = new_from;
}
} else {
gchar *tmp = decode_uri_gdup(value);
gchar *new_cc = g_strdup_printf("%s, %s", *cc, tmp);
+ g_free(tmp);
g_free(*cc);
*cc = new_cc;
}
} else {
gchar *tmp = decode_uri_gdup(value);
gchar *new_bcc = g_strdup_printf("%s, %s", *bcc, tmp);
+ g_free(tmp);
g_free(*bcc);
*bcc = new_bcc;
}
} else if (body && !*body && !g_ascii_strcasecmp(field, "body")) {
*body = decode_uri_gdup(value);
} else if (body && !*body && !g_ascii_strcasecmp(field, "insert")) {
+ int i = 0;
gchar *tmp = decode_uri_gdup(value);
- if (!g_file_get_contents(tmp, body, NULL, NULL)) {
- g_warning("couldn't set insert file '%s' in body", value);
+
+ for (; forbidden_uris[i]; i++) {
+ if (strstr(tmp, forbidden_uris[i])) {
+ g_print("Refusing to insert '%s', potential private data leak\n",
+ tmp);
+ g_free(tmp);
+ tmp = NULL;
+ break;
+ }
+ }
+
+ if (tmp) {
+ if (!is_file_entry_regular(tmp)) {
+ g_warning("Refusing to insert '%s', not a regular file\n", tmp);
+ } else if (!g_file_get_contents(tmp, body, NULL, NULL)) {
+ g_warning("couldn't set insert file '%s' in body", value);
+ }
+
+ g_free(tmp);
}
- g_free(tmp);
} else if (attach && !g_ascii_strcasecmp(field, "attach")) {
int i = 0;
gchar *tmp = decode_uri_gdup(value);
+ gchar **my_att = g_malloc(sizeof(char *));
+
+ my_att[0] = NULL;
+
for (; forbidden_uris[i]; i++) {
if (strstr(tmp, forbidden_uris[i])) {
g_print("Refusing to attach '%s', potential private data leak\n",
tmp);
g_free(tmp);
+ g_free(my_att);
+ tmp = NULL;
break;
}
}
my_att = g_realloc(my_att, (sizeof(char *))*(num_attach+1));
my_att[num_attach-1] = tmp;
my_att[num_attach] = NULL;
+ *attach = my_att;
}
} else if (inreplyto && !*inreplyto &&
!g_ascii_strcasecmp(field, "in-reply-to")) {
}
}
- if (attach)
- *attach = my_att;
return 0;
}
return g_file_test(file, G_FILE_TEST_EXISTS);
}
+gboolean is_file_entry_regular(const gchar *file)
+{
+ if (file == NULL)
+ return FALSE;
+
+ return g_file_test(file, G_FILE_TEST_IS_REGULAR);
+}
+
gboolean dirent_is_regular_file(struct dirent *d)
{
#if !defined(G_OS_WIN32) && defined(HAVE_DIRENT_D_TYPE)
gchar **argv;
gint ret;
+ cm_return_val_if_fail(cmdline != NULL, -1);
+
debug_print("execute_command_line(): executing: %s\n", cmdline?cmdline:"(null)");
argv = strsplit_with_quote(cmdline, " ", 0);
return child_stdout;
}
+FILE *get_command_output_stream(const char* cmdline)
+{
+ GPid pid;
+ GError *err = NULL;
+ gchar **argv = NULL;
+ int fd;
+
+ cm_return_val_if_fail(cmdline != NULL, NULL);
+
+ debug_print("get_command_output_stream(): executing: %s\n", cmdline);
+
+ /* turn the command-line string into an array */
+ if (!g_shell_parse_argv(cmdline, NULL, &argv, &err)) {
+ g_warning("could not parse command line from '%s': %s\n", cmdline, err->message);
+ g_error_free(err);
+ return NULL;
+ }
+
+ if (!g_spawn_async_with_pipes(NULL, argv, NULL, G_SPAWN_SEARCH_PATH,
+ NULL, NULL, &pid, NULL, &fd, NULL, &err)
+ && err)
+ {
+ g_warning("could not spawn '%s': %s\n", cmdline, err->message);
+ g_error_free(err);
+ g_strfreev(argv);
+ return NULL;
+ }
+
+ g_strfreev(argv);
+ return fdopen(fd, "r");
+}
+
static gint is_unchanged_uri_char(char c)
{
switch (c) {
static gboolean is_toplvl_domain(GHashTable *tab, const gchar *first, const gchar *last)
{
- const gint MAX_LVL_DOM_NAME_LEN = 6;
- gchar buf[MAX_LVL_DOM_NAME_LEN + 1];
- const gchar *m = buf + MAX_LVL_DOM_NAME_LEN + 1;
+ gchar buf[BUFFSIZE + 1];
+ const gchar *m = buf + BUFFSIZE + 1;
register gchar *p;
- if (last - first > MAX_LVL_DOM_NAME_LEN || first > last)
+ if (last - first > BUFFSIZE || first > last)
return FALSE;
for (p = buf; p < m && first < last; *p++ = *first++)
g_free(tmp);
if (strlen(out) != *out_len) {
- g_warning ("strlen(out) %zd != *out_len %" G_GSIZE_FORMAT, strlen(out), *out_len);
+ g_warning ("strlen(out) %"G_GSIZE_FORMAT" != *out_len %"G_GSIZE_FORMAT, strlen(out), *out_len);
}
return out;
/* Read data from the source into buf. */
#if defined G_OS_WIN32
if (!CryptGenRandom(rnd, count, buf)) {
- debug_print("Could not read %zd random bytes.\n", count);
+ debug_print("Could not read %"G_GSIZE_FORMAT" random bytes.\n", count);
CryptReleaseContext(rnd, 0);
return FALSE;
}
return TRUE;
}
+#ifdef G_OS_WIN32
+gchar *win32_debug_log_path(void)
+{
+ return g_strconcat(g_get_tmp_dir(), G_DIR_SEPARATOR_S,
+ "claws-win32.log", NULL);
+}
+#endif