summaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
Diffstat (limited to 'utils')
-rw-r--r--utils/config.h9
-rw-r--r--utils/corestringlist.h1
-rw-r--r--utils/file.c57
-rw-r--r--utils/filename.c88
-rw-r--r--utils/idna.c8
-rw-r--r--utils/inet.h11
-rw-r--r--utils/libdom.c123
-rw-r--r--utils/libdom.h23
-rw-r--r--utils/log.c5
-rw-r--r--utils/log.h1
-rw-r--r--utils/nscolour.c31
-rw-r--r--utils/nsoption.c13
-rw-r--r--utils/ssl_certs.c35
-rw-r--r--utils/useragent.c15
-rw-r--r--utils/utf8.c206
-rw-r--r--utils/utils.h27
16 files changed, 278 insertions, 375 deletions
diff --git a/utils/config.h b/utils/config.h
index 0227f4177..f54326dba 100644
--- a/utils/config.h
+++ b/utils/config.h
@@ -146,6 +146,15 @@ char *realpath(const char *path, char *resolved_path);
#undef HAVE_SCANDIR
#endif
+#define HAVE_DIRFD
+#define HAVE_UNLINKAT
+#define HAVE_FSTATAT
+#if (defined(_WIN32) || defined(__riscos__) || defined(__HAIKU__) || defined(__BEOS__) || defined(__amigaos4__) || defined(__AMIGA__) || defined(__MINT__))
+#undef HAVE_DIRFD
+#undef HAVE_UNLINKAT
+#undef HAVE_FSTATAT
+#endif
+
#define HAVE_REGEX
#if (defined(__serenity__))
#undef HAVE_REGEX
diff --git a/utils/corestringlist.h b/utils/corestringlist.h
index b253b3b56..5cdbb3af7 100644
--- a/utils/corestringlist.h
+++ b/utils/corestringlist.h
@@ -167,6 +167,7 @@ CORESTRING_LWC_VALUE(application_octet_stream, "application/octet-stream");
CORESTRING_LWC_VALUE(image_gif, "image/gif");
CORESTRING_LWC_VALUE(image_png, "image/png");
CORESTRING_LWC_VALUE(image_jpeg, "image/jpeg");
+CORESTRING_LWC_VALUE(image_jxl, "image/jxl");
CORESTRING_LWC_VALUE(image_bmp, "image/bmp");
CORESTRING_LWC_VALUE(image_vnd_microsoft_icon, "image/vnd.microsoft.icon");
CORESTRING_LWC_VALUE(image_webp, "image/webp");
diff --git a/utils/file.c b/utils/file.c
index c460e49e9..75a8a1c03 100644
--- a/utils/file.c
+++ b/utils/file.c
@@ -26,6 +26,7 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
+#include <fcntl.h>
#include <errno.h>
#include "desktop/gui_internal.h"
@@ -318,16 +319,13 @@ nserror netsurf_mkdir_all(const char *fname)
nserror
netsurf_recursive_rm(const char *path)
{
- struct dirent **listing = NULL; /* directory entry listing */
- int nentries, ent;
+ DIR *parent;
+ struct dirent *entry;
nserror ret = NSERROR_OK;
struct stat ent_stat; /* stat result of leaf entry */
- char *leafpath = NULL;
- const char *leafname;
-
- nentries = scandir(path, &listing, 0, alphasort);
- if (nentries < 0) {
+ parent = opendir(path);
+ if (parent == NULL) {
switch (errno) {
case ENOENT:
return NSERROR_NOT_FOUND;
@@ -336,26 +334,44 @@ netsurf_recursive_rm(const char *path)
}
}
- for (ent = 0; ent < nentries; ent++) {
- leafname = listing[ent]->d_name;
- if (strcmp(leafname, ".") == 0 ||
- strcmp(leafname, "..") == 0)
+ while ((entry = readdir(parent))) {
+ char *leafpath = NULL;
+
+ if (strcmp(entry->d_name, ".") == 0 ||
+ strcmp(entry->d_name, "..") == 0)
continue;
- ret = netsurf_mkpath(&leafpath, NULL, 2, path, leafname);
- if (ret != NSERROR_OK) goto out;
+
+ ret = netsurf_mkpath(&leafpath, NULL, 2, path, entry->d_name);
+ if (ret != NSERROR_OK)
+ goto out;
+
+#if (defined(HAVE_DIRFD) && defined(HAVE_FSTATAT))
+ if (fstatat(dirfd(parent), entry->d_name, &ent_stat,
+ AT_SYMLINK_NOFOLLOW) != 0) {
+#else
if (stat(leafpath, &ent_stat) != 0) {
+#endif
+ free(leafpath);
goto out_via_errno;
}
if (S_ISDIR(ent_stat.st_mode)) {
ret = netsurf_recursive_rm(leafpath);
- if (ret != NSERROR_OK) goto out;
+ if (ret != NSERROR_OK) {
+ free(leafpath);
+ goto out;
+ }
} else {
+#if (defined(HAVE_DIRFD) && defined(HAVE_UNLINKAT))
+ if (unlinkat(dirfd(parent), entry->d_name, 0) != 0) {
+#else
if (unlink(leafpath) != 0) {
+#endif
+ free(leafpath);
goto out_via_errno;
}
}
+
free(leafpath);
- leafpath = NULL;
}
if (rmdir(path) != 0) {
@@ -373,16 +389,7 @@ out_via_errno:
ret = NSERROR_UNKNOWN;
}
out:
- if (listing != NULL) {
- for (ent = 0; ent < nentries; ent++) {
- free(listing[ent]);
- }
- free(listing);
- }
-
- if (leafpath != NULL) {
- free(leafpath);
- }
+ closedir(parent);
return ret;
}
diff --git a/utils/filename.c b/utils/filename.c
index 00ade7409..346fa85cc 100644
--- a/utils/filename.c
+++ b/utils/filename.c
@@ -29,10 +29,13 @@
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
+#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
#include "utils/dirent.h"
+#include "utils/errors.h"
+#include "utils/file.h"
#include "utils/filename.h"
#include "utils/log.h"
#include "utils/utils.h"
@@ -55,7 +58,6 @@ static char filename_directory[256];
static struct directory *filename_create_directory(const char *prefix);
static bool filename_flush_directory(const char *folder, int depth);
-static bool filename_delete_recursive(char *folder);
/**
* Request a new, unique, filename.
@@ -272,6 +274,8 @@ bool filename_flush_directory(const char *folder, int depth)
}
parent = opendir(folder);
+ if (parent == NULL)
+ return false;
while ((entry = readdir(parent))) {
int written;
@@ -288,7 +292,12 @@ bool filename_flush_directory(const char *folder, int depth)
child[sizeof(child) - 1] = '\0';
}
+#if (defined(HAVE_DIRFD) && defined(HAVE_FSTATAT))
+ if (fstatat(dirfd(parent), entry->d_name, &statbuf,
+ AT_SYMLINK_NOFOLLOW) == -1) {
+#else
if (stat(child, &statbuf) == -1) {
+#endif
NSLOG(netsurf, INFO, "Unable to stat %s: %s", child,
strerror(errno));
continue;
@@ -354,14 +363,20 @@ bool filename_flush_directory(const char *folder, int depth)
/* delete or recurse */
if (del) {
- if (S_ISDIR(statbuf.st_mode))
- filename_delete_recursive(child);
-
- if (remove(child))
- NSLOG(netsurf, INFO, "Failed to remove '%s'",
- child);
- else
- changed = true;
+ if (S_ISDIR(statbuf.st_mode)) {
+ changed = (netsurf_recursive_rm(child) ==
+ NSERROR_OK);
+ } else {
+#if (defined(HAVE_DIRFD) && defined(HAVE_UNLINKAT))
+ if (unlinkat(dirfd(parent), entry->d_name, 0)) {
+#else
+ if (unlink(child)) {
+#endif
+ NSLOG(netsurf, INFO,
+ "Failed to remove '%s'", child);
+ } else
+ changed = true;
+ }
} else {
while (filename_flush_directory(child, depth + 1));
}
@@ -374,61 +389,6 @@ bool filename_flush_directory(const char *folder, int depth)
/**
- * Recursively deletes the contents of a directory
- *
- * \param folder the directory to delete
- * \return true on success, false otherwise
- */
-bool filename_delete_recursive(char *folder)
-{
- DIR *parent;
- struct dirent *entry;
- char child[256];
- struct stat statbuf;
-
- parent = opendir(folder);
-
- while ((entry = readdir(parent))) {
- int written;
-
- /* Ignore '.' and '..' */
- if (strcmp(entry->d_name, ".") == 0 ||
- strcmp(entry->d_name, "..") == 0)
- continue;
-
- written = snprintf(child, sizeof(child), "%s/%s",
- folder, entry->d_name);
- if (written == sizeof(child)) {
- child[sizeof(child) - 1] = '\0';
- }
-
- if (stat(child, &statbuf) == -1) {
- NSLOG(netsurf, INFO, "Unable to stat %s: %s", child,
- strerror(errno));
- continue;
- }
-
- if (S_ISDIR(statbuf.st_mode)) {
- if (!filename_delete_recursive(child)) {
- closedir(parent);
- return false;
- }
- }
-
- if (remove(child)) {
- NSLOG(netsurf, INFO, "Failed to remove '%s'", child);
- closedir(parent);
- return false;
- }
- }
-
- closedir(parent);
-
- return true;
-}
-
-
-/**
* Creates a new directory.
*
* \param prefix the prefix to use, or NULL to allocate a new one
diff --git a/utils/idna.c b/utils/idna.c
index 628ef1fac..3ce3e1be1 100644
--- a/utils/idna.c
+++ b/utils/idna.c
@@ -440,7 +440,7 @@ static bool idna__is_valid(int32_t *label, size_t len)
/* 4. Check characters not DISALLOWED by RFC5892 */
if (idna_prop == IDNA_P_DISALLOWED) {
NSLOG(netsurf, INFO,
- "Check failed: character %"PRIsizet" (%x) is DISALLOWED",
+ "Check failed: character %"PRIsizet" (%"PRIx32") is DISALLOWED",
i,
label[i]);
return false;
@@ -450,7 +450,7 @@ static bool idna__is_valid(int32_t *label, size_t len)
if (idna_prop == IDNA_P_CONTEXTJ) {
if (idna__contextj_rule(label, i, len) == false) {
NSLOG(netsurf, INFO,
- "Check failed: character %"PRIsizet" (%x) does not conform to CONTEXTJ rule",
+ "Check failed: character %"PRIsizet" (%"PRIx32") does not conform to CONTEXTJ rule",
i,
label[i]);
return false;
@@ -462,7 +462,7 @@ static bool idna__is_valid(int32_t *label, size_t len)
if (idna_prop == IDNA_P_CONTEXTO) {
if (idna__contexto_rule(label[i]) == false) {
NSLOG(netsurf, INFO,
- "Check failed: character %"PRIsizet" (%x) has no CONTEXTO rule defined",
+ "Check failed: character %"PRIsizet" (%"PRIx32") has no CONTEXTO rule defined",
i,
label[i]);
return false;
@@ -472,7 +472,7 @@ static bool idna__is_valid(int32_t *label, size_t len)
/* 7. Check characters are not UNASSIGNED */
if (idna_prop == IDNA_P_UNASSIGNED) {
NSLOG(netsurf, INFO,
- "Check failed: character %"PRIsizet" (%x) is UNASSIGNED",
+ "Check failed: character %"PRIsizet" (%"PRIx32") is UNASSIGNED",
i,
label[i]);
return false;
diff --git a/utils/inet.h b/utils/inet.h
index da1798432..29010efc1 100644
--- a/utils/inet.h
+++ b/utils/inet.h
@@ -40,6 +40,15 @@
#include <arpa/inet.h>
#include <sys/select.h>
+#define ns_close_socket close
+
+#ifdef WITH_AMISSL
+/* AmiSSL needs everything to be using bsdsocket directly to avoid conflicts */
+#include <proto/bsdsocket.h>
+#undef ns_close_socket
+#define ns_close_socket CloseSocket
+#endif
+
#else
#include <winsock2.h>
@@ -49,6 +58,8 @@
#define EAFNOSUPPORT WSAEAFNOSUPPORT
#endif
+#define ns_close_socket closesocket
+
#endif
diff --git a/utils/libdom.c b/utils/libdom.c
index a996e98bf..c39aad343 100644
--- a/utils/libdom.c
+++ b/utils/libdom.c
@@ -28,129 +28,6 @@
#include "utils/log.h"
#include "utils/libdom.h"
-/* exported interface documented in libdom.h */
-bool libdom_treewalk(dom_node *root,
- bool (*callback)(dom_node *node, dom_string *name, void *ctx),
- void *ctx)
-{
- dom_node *node;
- bool result = true;
-
- node = dom_node_ref(root); /* tree root */
-
- while (node != NULL) {
- dom_node *next = NULL;
- dom_node_type type;
- dom_string *name;
- dom_exception exc;
-
- exc = dom_node_get_first_child(node, &next);
- if (exc != DOM_NO_ERR) {
- dom_node_unref(node);
- break;
- }
-
- if (next != NULL) {
- /* 1. Got children */
- dom_node_unref(node);
- node = next;
- } else {
- /* No children; siblings & ancestor's siblings */
- while (node != NULL) {
- exc = dom_node_get_next_sibling(node, &next);
- if (exc != DOM_NO_ERR) {
- dom_node_unref(node);
- node = NULL;
- break;
- }
-
- if (next != NULL) {
- /* 2. Got sibling */
- break;
- }
-
- exc = dom_node_get_parent_node(node, &next);
- if (exc != DOM_NO_ERR) {
- dom_node_unref(node);
- node = NULL;
- break;
- }
-
- /* 3. Try parent */
- dom_node_unref(node);
- node = next;
- }
-
- if (node == NULL)
- break;
-
- dom_node_unref(node);
- node = next;
- }
-
- assert(node != NULL);
-
- exc = dom_node_get_node_type(node, &type);
- if ((exc != DOM_NO_ERR) || (type != DOM_ELEMENT_NODE))
- continue;
-
- exc = dom_node_get_node_name(node, &name);
- if (exc != DOM_NO_ERR)
- continue;
-
- result = callback(node, name, ctx);
-
- dom_string_unref(name);
-
- if (result == false) {
- break; /* callback caused early termination */
- }
-
- }
- return result;
-}
-
-
-/* libdom_treewalk context for libdom_find_element */
-struct find_element_ctx {
- lwc_string *search;
- dom_node *found;
-};
-
-/* libdom_treewalk callback for libdom_find_element */
-static bool libdom_find_element_callback(dom_node *node, dom_string *name,
- void *ctx)
-{
- struct find_element_ctx *data = ctx;
-
- if (dom_string_caseless_lwc_isequal(name, data->search)) {
- /* Found element */
- data->found = node;
- return false; /* Discontinue search */
- }
-
- return true; /* Continue search */
-}
-
-
-/* exported interface documented in libdom.h */
-dom_node *libdom_find_element(dom_node *node, lwc_string *element_name)
-{
- struct find_element_ctx data;
-
- assert(element_name != NULL);
-
- if (node == NULL)
- return NULL;
-
- data.search = element_name;
- data.found = NULL;
-
- libdom_treewalk(node, libdom_find_element_callback, &data);
-
- return data.found;
-}
-
/* exported interface documented in libdom.h */
dom_node *libdom_find_first_element(dom_node *parent, lwc_string *element_name)
diff --git a/utils/libdom.h b/utils/libdom.h
index 306aa0f8b..63841934f 100644
--- a/utils/libdom.h
+++ b/utils/libdom.h
@@ -33,29 +33,6 @@
#include <dom/bindings/hubbub/errors.h>
/**
- * depth-first walk the dom calling callback for each element
- *
- * \param root the dom node to use as the root of the tree walk
- * \param callback The function called for each element
- * \param ctx The context passed to the callback.
- * \return true if all nodes were examined, false if the callback terminated
- * the walk early.
- */
-bool libdom_treewalk(dom_node *root,
- bool (*callback)(dom_node *node, dom_string *name, void *ctx),
- void *ctx);
-
-/**
- * Search the descendants of a node for an element.
- *
- * \param node dom_node to search children of, or NULL
- * \param element_name name of element to find
- * \return first child of node which is an element and matches name, or
- * NULL if not found or parameter node is NULL
- */
-dom_node *libdom_find_element(dom_node *node, lwc_string *element_name);
-
-/**
* Search children of a node for first named element
* \param parent dom_node to search children of, or NULL
* \param element_name name of element to find
diff --git a/utils/log.c b/utils/log.c
index 68b188e0f..a083b5720 100644
--- a/utils/log.c
+++ b/utils/log.c
@@ -99,6 +99,7 @@ NSLOG_DEFINE_CATEGORY(plot, "Rendering system");
NSLOG_DEFINE_CATEGORY(schedule, "Scheduler");
NSLOG_DEFINE_CATEGORY(fbtk, "Framebuffer toolkit");
NSLOG_DEFINE_CATEGORY(layout, "Layout");
+NSLOG_DEFINE_CATEGORY(flex, "Flex");
NSLOG_DEFINE_CATEGORY(dukky, "Duktape JavaScript Binding");
NSLOG_DEFINE_CATEGORY(jserrors, "JavaScript error messages");
@@ -285,7 +286,7 @@ nserror nslog_init(nslog_ensure_t *ensure, int *pargc, char **argv)
/* exported interface documented in utils/log.h */
nserror
-nslog_set_filter_by_options()
+nslog_set_filter_by_options(void)
{
if (verbose_log)
return nslog_set_filter(nsoption_charp(verbose_filter));
@@ -295,7 +296,7 @@ nslog_set_filter_by_options()
/* exported interface documented in utils/log.h */
void
-nslog_finalise()
+nslog_finalise(void)
{
NSLOG(netsurf, INFO,
"Finalising logging, please report any further messages");
diff --git a/utils/log.h b/utils/log.h
index 02a886c01..b7aa83358 100644
--- a/utils/log.h
+++ b/utils/log.h
@@ -84,6 +84,7 @@ NSLOG_DECLARE_CATEGORY(plot);
NSLOG_DECLARE_CATEGORY(schedule);
NSLOG_DECLARE_CATEGORY(fbtk);
NSLOG_DECLARE_CATEGORY(layout);
+NSLOG_DECLARE_CATEGORY(flex);
NSLOG_DECLARE_CATEGORY(dukky);
NSLOG_DECLARE_CATEGORY(jserrors);
diff --git a/utils/nscolour.c b/utils/nscolour.c
index a07175201..5a772b8a6 100644
--- a/utils/nscolour.c
+++ b/utils/nscolour.c
@@ -28,6 +28,7 @@
#include <stddef.h>
#include <stdbool.h>
+#include "netsurf/inttypes.h"
#include "netsurf/plot_style.h"
#include "utils/errors.h"
@@ -211,49 +212,49 @@ nserror nscolour_get_stylesheet(const char **stylesheet_out)
ret = snprintf(buffer, sizeof(buffer),
".ns-odd-bg {\n"
- "\tbackground-color: #%06x;\n"
+ "\tbackground-color: #%06"PRIx32";\n"
"}\n"
".ns-odd-bg-hover {\n"
- "\tbackground-color: #%06x;\n"
+ "\tbackground-color: #%06"PRIx32";\n"
"}\n"
".ns-odd-fg {\n"
- "\tcolor: #%06x;\n"
+ "\tcolor: #%06"PRIx32";\n"
"}\n"
".ns-odd-fg-subtle {\n"
- "\tcolor: #%06x;\n"
+ "\tcolor: #%06"PRIx32";\n"
"}\n"
".ns-odd-fg-faded {\n"
- "\tcolor: #%06x;\n"
+ "\tcolor: #%06"PRIx32";\n"
"}\n"
".ns-odd-fg-good {\n"
- "\tcolor: #%06x;\n"
+ "\tcolor: #%06"PRIx32";\n"
"}\n"
".ns-odd-fg-bad {\n"
- "\tcolor: #%06x;\n"
+ "\tcolor: #%06"PRIx32";\n"
"}\n"
".ns-even-bg {\n"
- "\tbackground-color: #%06x;\n"
+ "\tbackground-color: #%06"PRIx32";\n"
"}\n"
".ns-even-bg-hover {\n"
- "\tbackground-color: #%06x;\n"
+ "\tbackground-color: #%06"PRIx32";\n"
"}\n"
".ns-even-fg {\n"
- "\tcolor: #%06x;\n"
+ "\tcolor: #%06"PRIx32";\n"
"}\n"
".ns-even-fg-subtle {\n"
- "\tcolor: #%06x;\n"
+ "\tcolor: #%06"PRIx32";\n"
"}\n"
".ns-even-fg-faded {\n"
- "\tcolor: #%06x;\n"
+ "\tcolor: #%06"PRIx32";\n"
"}\n"
".ns-even-fg-good {\n"
- "\tcolor: #%06x;\n"
+ "\tcolor: #%06"PRIx32";\n"
"}\n"
".ns-even-fg-bad {\n"
- "\tcolor: #%06x;\n"
+ "\tcolor: #%06"PRIx32";\n"
"}\n"
".ns-border {\n"
- "\tborder-color: #%06x;\n"
+ "\tborder-color: #%06"PRIx32";\n"
"}\n",
colour_rb_swap(nscolours[NSCOLOUR_WIN_ODD_BG]),
colour_rb_swap(nscolours[NSCOLOUR_WIN_ODD_BG_HOVER]),
diff --git a/utils/nsoption.c b/utils/nsoption.c
index a8a29b3bf..7306dee1b 100644
--- a/utils/nsoption.c
+++ b/utils/nsoption.c
@@ -32,6 +32,7 @@
#include <string.h>
#include <strings.h>
+#include "netsurf/inttypes.h"
#include "netsurf/plot_style.h"
#include "utils/errors.h"
#include "utils/log.h"
@@ -112,7 +113,7 @@ strtooption(const char *value, struct nsoption_s *option)
break;
case OPTION_COLOUR:
- if (sscanf(value, "%x", &rgbcolour) == 1) {
+ if (sscanf(value, "%"SCNx32"", &rgbcolour) == 1) {
option->value.c = (((0x000000FF & rgbcolour) << 16) |
((0x0000FF00 & rgbcolour) << 0) |
((0x00FF0000 & rgbcolour) >> 16));
@@ -323,7 +324,7 @@ nsoption_output(FILE *fp,
rgbcolour = (((0x000000FF & opts[entry].value.c) << 16) |
((0x0000FF00 & opts[entry].value.c) << 0) |
((0x00FF0000 & opts[entry].value.c) >> 16));
- fprintf(fp, "%s:%06x\n",
+ fprintf(fp, "%s:%06"PRIx32"\n",
opts[entry].key,
rgbcolour);
@@ -387,10 +388,10 @@ nsoption_output_value_html(struct nsoption_s *option,
slen = snprintf(string + pos,
size - pos,
"<span style=\"font-family:Monospace;\">"
- "#%06X"
+ "#%06"PRIX32
"</span> "
- "<span style=\"background-color: #%06x; "
- "border: 1px solid #%06x; "
+ "<span style=\"background-color: #%06"PRIx32"; "
+ "border: 1px solid #%06"PRIx32"; "
"display: inline-block; "
"width: 1em; height: 1em;\">"
"</span>",
@@ -459,7 +460,7 @@ nsoption_output_value_text(struct nsoption_s *option,
rgbcolour = (((0x000000FF & option->value.c) << 16) |
((0x0000FF00 & option->value.c) << 0) |
((0x00FF0000 & option->value.c) >> 16));
- slen = snprintf(string + pos, size - pos, "%06x", rgbcolour);
+ slen = snprintf(string + pos, size - pos, "%06"PRIx32, rgbcolour);
break;
case OPTION_STRING:
diff --git a/utils/ssl_certs.c b/utils/ssl_certs.c
index d0f2a6c18..8546165ac 100644
--- a/utils/ssl_certs.c
+++ b/utils/ssl_certs.c
@@ -248,12 +248,23 @@ nserror cert_chain_to_query(struct cert_chain *chain, struct nsurl **url_out )
urlstrlen = snprintf((char *)urlstr, allocsize, "about:certificate");
for (depth = 0; depth < chain->depth; depth++) {
+ int written;
nsuerror nsures;
size_t output_length;
- urlstrlen += snprintf((char *)urlstr + urlstrlen,
- allocsize - urlstrlen,
- "&cert=");
+ written = snprintf((char *)urlstr + urlstrlen,
+ allocsize - urlstrlen,
+ "&cert=");
+ if (written < 0) {
+ free(urlstr);
+ return NSERROR_UNKNOWN;
+ }
+ if ((size_t)written >= allocsize - urlstrlen) {
+ free(urlstr);
+ return NSERROR_UNKNOWN;
+ }
+
+ urlstrlen += (size_t)written;
output_length = allocsize - urlstrlen;
nsures = nsu_base64_encode_url(
@@ -268,10 +279,20 @@ nserror cert_chain_to_query(struct cert_chain *chain, struct nsurl **url_out )
urlstrlen += output_length;
if (chain->certs[depth].err != SSL_CERT_ERR_OK) {
- urlstrlen += snprintf((char *)urlstr + urlstrlen,
- allocsize - urlstrlen,
- "&certerr=%d",
- chain->certs[depth].err);
+ written = snprintf((char *)urlstr + urlstrlen,
+ allocsize - urlstrlen,
+ "&certerr=%d",
+ chain->certs[depth].err);
+ if (written < 0) {
+ free(urlstr);
+ return NSERROR_UNKNOWN;
+ }
+ if ((size_t)written >= allocsize - urlstrlen) {
+ free(urlstr);
+ return NSERROR_UNKNOWN;
+ }
+
+ urlstrlen += (size_t)written;
}
}
diff --git a/utils/useragent.c b/utils/useragent.c
index 3d93a97b2..547999c7c 100644
--- a/utils/useragent.c
+++ b/utils/useragent.c
@@ -19,6 +19,7 @@
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include "utils/config.h"
#include "utils/utsname.h"
@@ -29,7 +30,7 @@
static const char *core_user_agent_string = NULL;
#ifndef NETSURF_UA_FORMAT_STRING
-#define NETSURF_UA_FORMAT_STRING "NetSurf/%d.%d (%s)"
+#define NETSURF_UA_FORMAT_STRING "Mozilla/5.0 (%s) NetSurf/%d.%d"
#endif
/**
@@ -46,12 +47,16 @@ user_agent_build_string(void)
if (uname(&un) >= 0) {
sysname = un.sysname;
+ if (strcmp(sysname, "Linux") == 0) {
+ /* Force desktop, not mobile */
+ sysname = "X11; Linux";
+ }
}
len = snprintf(NULL, 0, NETSURF_UA_FORMAT_STRING,
+ sysname,
netsurf_version_major,
- netsurf_version_minor,
- sysname);
+ netsurf_version_minor);
ua_string = malloc(len + 1);
if (!ua_string) {
/** \todo this needs handling better */
@@ -59,9 +64,9 @@ user_agent_build_string(void)
}
snprintf(ua_string, len + 1,
NETSURF_UA_FORMAT_STRING,
+ sysname,
netsurf_version_major,
- netsurf_version_minor,
- sysname);
+ netsurf_version_minor);
core_user_agent_string = ua_string;
diff --git a/utils/utf8.c b/utils/utf8.c
index f0ac0c9b2..3eedd0810 100644
--- a/utils/utf8.c
+++ b/utils/utf8.c
@@ -32,6 +32,7 @@
#include "utils/log.h"
#include "utils/utf8.h"
+#include "netsurf/inttypes.h"
#include "netsurf/utf8.h"
#include "desktop/gui_internal.h"
@@ -44,7 +45,7 @@ uint32_t utf8_to_ucs4(const char *s_in, size_t l)
parserutils_error perror;
perror = parserutils_charset_utf8_to_ucs4((const uint8_t *) s_in, l,
- &ucs4, &len);
+ &ucs4, &len);
if (perror != PARSERUTILS_OK)
ucs4 = 0xfffd;
@@ -106,7 +107,7 @@ size_t utf8_char_byte_length(const char *s)
parserutils_error perror;
perror = parserutils_charset_utf8_char_byte_length((const uint8_t *) s,
- &len);
+ &len);
assert(perror == PARSERUTILS_OK);
return len;
@@ -131,7 +132,7 @@ size_t utf8_next(const char *s, size_t l, size_t o)
parserutils_error perror;
perror = parserutils_charset_utf8_next((const uint8_t *) s, l, o,
- &next);
+ &next);
assert(perror == PARSERUTILS_OK);
return next;
@@ -151,6 +152,47 @@ static inline void utf8_clear_cd_cache(void)
last_cd.cd = 0;
}
+/**
+ * obtain a cached conversion descriptor
+ *
+ * either return the cached conversion descriptor or create one if required
+ */
+static nserror
+get_cached_cd(const char *enc_from, const char *enc_to, iconv_t *cd_out)
+{
+ iconv_t cd;
+ /* we cache the last used conversion descriptor,
+ * so check if we're trying to use it here */
+ if (strncasecmp(last_cd.from, enc_from, sizeof(last_cd.from)) == 0 &&
+ strncasecmp(last_cd.to, enc_to, sizeof(last_cd.to)) == 0 &&
+ last_cd.cd != 0) {
+ *cd_out = last_cd.cd;
+ return NSERROR_OK;
+ }
+
+ /* no match, so create a new cd */
+ cd = iconv_open(enc_to, enc_from);
+ if (cd == (iconv_t) -1) {
+ if (errno == EINVAL) {
+ return NSERROR_BAD_ENCODING;
+ }
+ /* default to no memory */
+ return NSERROR_NOMEM;
+ }
+
+ /* close the last cd - we don't care if this fails */
+ if (last_cd.cd) {
+ iconv_close(last_cd.cd);
+ }
+
+ /* and safely copy the to/from/cd data into last_cd */
+ snprintf(last_cd.from, sizeof(last_cd.from), "%s", enc_from);
+ snprintf(last_cd.to, sizeof(last_cd.to), "%s", enc_to);
+ *cd_out = last_cd.cd = cd;
+
+ return NSERROR_OK;
+}
+
/* exported interface documented in utils/utf8.h */
nserror utf8_finalise(void)
{
@@ -168,95 +210,72 @@ nserror utf8_finalise(void)
* Convert a string from one encoding to another
*
* \param string The NULL-terminated string to convert
- * \param len Length of input string to consider (in bytes), or 0
+ * \param slen Length of input string to consider (in bytes), or 0
* \param from The encoding name to convert from
* \param to The encoding name to convert to
- * \param result Pointer to location in which to store result.
- * \param result_len Pointer to location in which to store result length.
+ * \param result_out Pointer to location in which to store result.
+ * \param result_len_out Pointer to location in which to store result length.
* \return NSERROR_OK for no error, NSERROR_NOMEM on allocation error,
* NSERROR_BAD_ENCODING for a bad character encoding
*/
static nserror
utf8_convert(const char *string,
- size_t len,
+ size_t slen,
const char *from,
const char *to,
- char **result,
- size_t *result_len)
+ char **result_out,
+ size_t *result_len_out)
{
iconv_t cd;
- char *temp, *out, *in;
- size_t slen, rlen;
-
- assert(string && from && to && result);
-
- if (string[0] == '\0') {
- /* On AmigaOS, iconv() returns an error if we pass an
- * empty string. This prevents iconv() being called as
- * there is no conversion necessary anyway. */
- *result = strdup("");
- if (!(*result)) {
- *result = NULL;
- return NSERROR_NOMEM;
- }
+ char *temp, *out, *in, *result;
+ size_t result_len;
+ nserror res;
- return NSERROR_OK;
+ assert(string && from && to && result_out);
+
+ /* calculate the source length if not given */
+ if (slen==0) {
+ slen = strlen(string);
}
- if (strcasecmp(from, to) == 0) {
- /* conversion from an encoding to itself == strdup */
- slen = len ? len : strlen(string);
- *(result) = strndup(string, slen);
- if (!(*result)) {
- *(result) = NULL;
+ /* process the empty string separately avoiding any conversion
+ * check for the source and destination encoding being the same
+ *
+ * This optimisation is necessary on AmigaOS as iconv()
+ * returns an error if an empty string is passed.
+ */
+ if ((slen == 0) || (strcasecmp(from, to) == 0)) {
+ *result_out = strndup(string, slen);
+ if (*result_out == NULL) {
return NSERROR_NOMEM;
}
+ if (result_len_out != NULL) {
+ *result_len_out = slen;
+ }
return NSERROR_OK;
}
in = (char *)string;
- /* we cache the last used conversion descriptor,
- * so check if we're trying to use it here */
- if (strncasecmp(last_cd.from, from, sizeof(last_cd.from)) == 0 &&
- strncasecmp(last_cd.to, to, sizeof(last_cd.to)) == 0) {
- cd = last_cd.cd;
- }
- else {
- /* no match, so create a new cd */
- cd = iconv_open(to, from);
- if (cd == (iconv_t)-1) {
- if (errno == EINVAL)
- return NSERROR_BAD_ENCODING;
- /* default to no memory */
- return NSERROR_NOMEM;
- }
-
- /* close the last cd - we don't care if this fails */
- if (last_cd.cd)
- iconv_close(last_cd.cd);
-
- /* and copy the to/from/cd data into last_cd */
- snprintf(last_cd.from, sizeof(last_cd.from), "%s", from);
- snprintf(last_cd.to, sizeof(last_cd.to), "%s", to);
- last_cd.cd = cd;
+ res = get_cached_cd(from, to, &cd);
+ if (res != NSERROR_OK) {
+ return res;
}
- slen = len ? len : strlen(string);
/* Worst case = ASCII -> UCS4, so allocate an output buffer
* 4 times larger than the input buffer, and add 4 bytes at
* the end for the NULL terminator
*/
- rlen = slen * 4 + 4;
+ result_len = slen * 4 + 4;
- temp = out = malloc(rlen);
+ temp = out = malloc(result_len);
if (!out) {
return NSERROR_NOMEM;
}
/* perform conversion */
- if (iconv(cd, (void *) &in, &slen, &out, &rlen) == (size_t)-1) {
+ if (iconv(cd, (void *) &in, &slen, &out, &result_len) == (size_t)-1) {
free(temp);
/* clear the cached conversion descriptor as it's invalid */
if (last_cd.cd)
@@ -270,19 +289,22 @@ utf8_convert(const char *string,
return NSERROR_NOMEM;
}
- *(result) = realloc(temp, out - temp + 4);
- if (!(*result)) {
+ result_len = out - temp;
+
+ /* resize buffer allowing for null termination */
+ result = realloc(temp, result_len + 4);
+ if (result == NULL) {
free(temp);
- *(result) = NULL; /* for sanity's sake */
return NSERROR_NOMEM;
}
/* NULL terminate - needs 4 characters as we may have
* converted to UTF-32 */
- memset((*result) + (out - temp), 0, 4);
+ memset(result + result_len, 0, 4);
- if (result_len != NULL) {
- *result_len = (out - temp);
+ *result_out = result;
+ if (result_len_out != NULL) {
+ *result_len_out = result_len;
}
return NSERROR_OK;
@@ -290,14 +312,14 @@ utf8_convert(const char *string,
/* exported interface documented in utils/utf8.h */
nserror utf8_to_enc(const char *string, const char *encname,
- size_t len, char **result)
+ size_t len, char **result)
{
return utf8_convert(string, len, "UTF-8", encname, result, NULL);
}
/* exported interface documented in utils/utf8.h */
nserror utf8_from_enc(const char *string, const char *encname,
- size_t len, char **result, size_t *result_len)
+ size_t len, char **result, size_t *result_len)
{
return utf8_convert(string, len, encname, "UTF-8", result, result_len);
}
@@ -325,10 +347,10 @@ utf8_convert_html_chunk(iconv_t cd,
return NSERROR_NOMEM;
ucs4 = utf8_to_ucs4(chunk, inlen);
- esclen = snprintf(escape, sizeof(escape), "&#x%06x;", ucs4);
+ esclen = snprintf(escape, sizeof(escape), "&#x%06"PRIx32";", ucs4);
pescape = escape;
ret = iconv(cd, (void *) &pescape, &esclen,
- (void *) out, outlen);
+ (void *) out, outlen);
if (ret == (size_t) -1)
return NSERROR_NOMEM;
@@ -340,45 +362,26 @@ utf8_convert_html_chunk(iconv_t cd,
return NSERROR_OK;
}
+
+
/* exported interface documented in utils/utf8.h */
nserror
-utf8_to_html(const char *string, const char *encname, size_t len, char **result)
+utf8_to_html(const char *string, const char *encname, size_t len, char **result_out)
{
iconv_t cd;
const char *in;
- char *out, *origout;
+ char *out, *origout, *result;
size_t off, prev_off, inlen, outlen, origoutlen, esclen;
nserror ret;
char *pescape, escape[11];
+ nserror res;
if (len == 0)
len = strlen(string);
- /* we cache the last used conversion descriptor,
- * so check if we're trying to use it here */
- if (strncasecmp(last_cd.from, "UTF-8", sizeof(last_cd.from)) == 0 &&
- strncasecmp(last_cd.to, encname,
- sizeof(last_cd.to)) == 0 &&
- last_cd.cd != 0) {
- cd = last_cd.cd;
- } else {
- /* no match, so create a new cd */
- cd = iconv_open(encname, "UTF-8");
- if (cd == (iconv_t) -1) {
- if (errno == EINVAL)
- return NSERROR_BAD_ENCODING;
- /* default to no memory */
- return NSERROR_NOMEM;
- }
-
- /* close the last cd - we don't care if this fails */
- if (last_cd.cd)
- iconv_close(last_cd.cd);
-
- /* and safely copy the to/from/cd data into last_cd */
- snprintf(last_cd.from, sizeof(last_cd.from), "UTF-8");
- snprintf(last_cd.to, sizeof(last_cd.to), "%s", encname);
- last_cd.cd = cd;
+ res = get_cached_cd("UTF-8", encname, &cd);
+ if (res != NSERROR_OK) {
+ return res;
}
/* Worst case is ASCII -> UCS4, with all characters escaped:
@@ -398,13 +401,13 @@ utf8_to_html(const char *string, const char *encname, size_t len, char **result)
while (off < len) {
/* Must escape '&', '<', and '>' */
if (string[off] == '&' || string[off] == '<' ||
- string[off] == '>') {
+ string[off] == '>') {
if (off - prev_off > 0) {
/* Emit chunk */
in = string + prev_off;
inlen = off - prev_off;
ret = utf8_convert_html_chunk(cd, in, inlen,
- &out, &outlen);
+ &out, &outlen);
if (ret != NSERROR_OK) {
free(origout);
iconv_close(cd);
@@ -415,10 +418,10 @@ utf8_to_html(const char *string, const char *encname, size_t len, char **result)
/* Emit mandatory escape */
esclen = snprintf(escape, sizeof(escape),
- "&#x%06x;", string[off]);
+ "&#x%06x;", string[off]);
pescape = escape;
ret = utf8_convert_html_chunk(cd, pescape, esclen,
- &out, &outlen);
+ &out, &outlen);
if (ret != NSERROR_OK) {
free(origout);
iconv_close(cd);
@@ -450,11 +453,12 @@ utf8_to_html(const char *string, const char *encname, size_t len, char **result)
outlen -= 4;
/* Shrink-wrap */
- *result = realloc(origout, origoutlen - outlen);
- if (*result == NULL) {
+ result = realloc(origout, origoutlen - outlen);
+ if (result == NULL) {
free(origout);
return NSERROR_NOMEM;
}
+ *result_out = result;
return NSERROR_OK;
}
diff --git a/utils/utils.h b/utils/utils.h
index 3995071cd..cb9e04b45 100644
--- a/utils/utils.h
+++ b/utils/utils.h
@@ -89,4 +89,31 @@
*/
bool is_dir(const char *path);
+/**
+ * switch fall through
+ */
+#if defined __cplusplus && defined __has_cpp_attribute
+ #if __has_cpp_attribute(fallthrough) && __cplusplus >= __has_cpp_attribute(fallthrough)
+ #define fallthrough [[fallthrough]]
+ #elif __has_cpp_attribute(gnu::fallthrough) && __STDC_VERSION__ >= __has_cpp_attribute(gnu::fallthrough)
+ #define fallthrough [[gnu::fallthrough]]
+ #elif __has_cpp_attribute(clang::fallthrough) && __STDC_VERSION__ >= __has_cpp_attribute(clang::fallthrough)
+ #define fallthrough [[clang::fallthrough]]
+ #endif
+#elif defined __STDC_VERSION__ && defined __has_c_attribute
+ #if __has_c_attribute(fallthrough) && __STDC_VERSION__ >= __has_c_attribute(fallthrough)
+ #define fallthrough [[fallthrough]]
+ #endif
+#endif
+#if !defined fallthrough && defined __has_attribute
+ #if __has_attribute(__fallthrough__)
+ #define fallthrough __attribute__((__fallthrough__))
+ #endif
+#endif
+#if !defined fallthrough
+/* early gcc and clang have no implicit fallthrough warning */
+ #define fallthrough do {} while(0)
+#endif
+
+
#endif