summaryrefslogtreecommitdiff
path: root/content/content.c
diff options
context:
space:
mode:
Diffstat (limited to 'content/content.c')
-rw-r--r--content/content.c852
1 files changed, 400 insertions, 452 deletions
diff --git a/content/content.c b/content/content.c
index 3a5628096..ae4718f54 100644
--- a/content/content.c
+++ b/content/content.c
@@ -23,20 +23,23 @@
#include <stdint.h>
#include <stdlib.h>
+#include <string.h>
#include <nsutils/time.h>
#include "netsurf/inttypes.h"
#include "utils/log.h"
#include "utils/messages.h"
+#include "utils/corestrings.h"
#include "netsurf/browser_window.h"
#include "netsurf/bitmap.h"
#include "netsurf/content.h"
#include "desktop/knockout.h"
-#include "desktop/gui_internal.h"
#include "content/content_protected.h"
+#include "content/textsearch.h"
#include "content/content_debug.h"
#include "content/hlcache.h"
+#include "content/urldb.h"
#define URL_FMT_SPC "%.140s"
@@ -47,85 +50,48 @@ const char * const content_status_name[] = {
"ERROR"
};
-static nserror content_llcache_callback(llcache_handle *llcache,
- const llcache_event *event, void *pw);
-static void content_convert(struct content *c);
-
/**
- * Initialise a new content structure.
+ * All data has arrived, convert for display.
*
- * \param c Content to initialise
- * \param handler Content handler
- * \param imime_type MIME type of content
- * \param params HTTP parameters
- * \param llcache Source data handle
- * \param fallback_charset Fallback charset
- * \param quirks Quirkiness of content
- * \return NSERROR_OK on success, appropriate error otherwise
+ * Calls the convert function for the content.
+ *
+ * - If the conversion succeeds, but there is still some processing required
+ * (eg. loading images), the content gets status CONTENT_STATUS_READY, and a
+ * CONTENT_MSG_READY is sent to all users.
+ * - If the conversion succeeds and is complete, the content gets status
+ * CONTENT_STATUS_DONE, and CONTENT_MSG_READY then CONTENT_MSG_DONE are sent.
+ * - If the conversion fails, CONTENT_MSG_ERROR is sent. The content will soon
+ * be destroyed and must no longer be used.
*/
-
-nserror content__init(struct content *c, const content_handler *handler,
- lwc_string *imime_type, const struct http_parameter *params,
- llcache_handle *llcache, const char *fallback_charset,
- bool quirks)
+static void content_convert(struct content *c)
{
- struct content_user *user_sentinel;
- nserror error;
-
- NSLOG(netsurf, INFO, "url "URL_FMT_SPC" -> %p",
- nsurl_access_log(llcache_handle_get_url(llcache)), c);
-
- user_sentinel = calloc(1, sizeof(struct content_user));
- if (user_sentinel == NULL) {
- return NSERROR_NOMEM;
- }
+ assert(c);
+ assert(c->status == CONTENT_STATUS_LOADING ||
+ c->status == CONTENT_STATUS_ERROR);
- if (fallback_charset != NULL) {
- c->fallback_charset = strdup(fallback_charset);
- if (c->fallback_charset == NULL) {
- free(user_sentinel);
- return NSERROR_NOMEM;
- }
- }
+ if (c->status != CONTENT_STATUS_LOADING)
+ return;
- c->llcache = llcache;
- c->mime_type = lwc_string_ref(imime_type);
- c->handler = handler;
- c->status = CONTENT_STATUS_LOADING;
- c->width = 0;
- c->height = 0;
- c->available_width = 0;
- c->available_height = 0;
- c->quirks = quirks;
- c->refresh = 0;
- nsu_getmonotonic_ms(&c->time);
- c->size = 0;
- c->title = NULL;
- c->active = 0;
- user_sentinel->callback = NULL;
- user_sentinel->pw = NULL;
- user_sentinel->next = NULL;
- c->user_list = user_sentinel;
- c->sub_status[0] = 0;
- c->locked = false;
- c->total_size = 0;
- c->http_code = 0;
- c->error_count = 0;
+ if (c->locked == true)
+ return;
- content_set_status(c, messages_get("Loading"));
+ NSLOG(netsurf, INFO, "content "URL_FMT_SPC" (%p)",
+ nsurl_access_log(llcache_handle_get_url(c->llcache)), c);
- /* Finally, claim low-level cache events */
- error = llcache_handle_change_callback(llcache,
- content_llcache_callback, c);
- if (error != NSERROR_OK) {
- lwc_string_unref(c->mime_type);
- return error;
+ if (c->handler->data_complete != NULL) {
+ c->locked = true;
+ if (c->handler->data_complete(c) == false) {
+ content_set_error(c);
+ }
+ /* Conversion to the READY state will unlock the content */
+ } else {
+ content_set_ready(c);
+ content_set_done(c);
}
-
- return NSERROR_OK;
}
+
/**
* Handler for low-level cache events
*
@@ -134,22 +100,26 @@ nserror content__init(struct content *c, const content_handler *handler,
* \param pw Pointer to our context
* \return NSERROR_OK on success, appropriate error otherwise
*/
-nserror content_llcache_callback(llcache_handle *llcache,
- const llcache_event *event, void *pw)
+static nserror
+content_llcache_callback(llcache_handle *llcache,
+ const llcache_event *event, void *pw)
{
struct content *c = pw;
union content_msg_data msg_data;
nserror error = NSERROR_OK;
switch (event->type) {
+ case LLCACHE_EVENT_GOT_CERTS:
+ /* Will never happen: handled in hlcache */
+ break;
case LLCACHE_EVENT_HAD_HEADERS:
/* Will never happen: handled in hlcache */
break;
case LLCACHE_EVENT_HAD_DATA:
if (c->handler->process_data != NULL) {
- if (c->handler->process_data(c,
- (const char *) event->data.data.buf,
- event->data.data.len) == false) {
+ if (c->handler->process_data(c,
+ (const char *) event->data.data.buf,
+ event->data.data.len) == false) {
llcache_handle_abort(c->llcache);
c->status = CONTENT_STATUS_ERROR;
/** \todo It's not clear what error this is */
@@ -158,26 +128,27 @@ nserror content_llcache_callback(llcache_handle *llcache,
}
break;
case LLCACHE_EVENT_DONE:
- {
- size_t source_size;
+ {
+ size_t source_size;
- (void) llcache_handle_get_source_data(llcache, &source_size);
+ (void) llcache_handle_get_source_data(llcache, &source_size);
- content_set_status(c, messages_get("Processing"));
- msg_data.explicit_status_text = NULL;
- content_broadcast(c, CONTENT_MSG_STATUS, &msg_data);
+ content_set_status(c, messages_get("Processing"));
+ msg_data.explicit_status_text = NULL;
+ content_broadcast(c, CONTENT_MSG_STATUS, &msg_data);
- content_convert(c);
- }
+ content_convert(c);
+ }
break;
case LLCACHE_EVENT_ERROR:
/** \todo Error page? */
c->status = CONTENT_STATUS_ERROR;
- msg_data.error = event->data.msg;
+ msg_data.errordata.errorcode = event->data.error.code;
+ msg_data.errordata.errormsg = event->data.error.msg;
content_broadcast(c, CONTENT_MSG_ERROR, &msg_data);
break;
case LLCACHE_EVENT_PROGRESS:
- content_set_status(c, event->data.msg);
+ content_set_status(c, event->data.progress_msg);
msg_data.explicit_status_text = NULL;
content_broadcast(c, CONTENT_MSG_STATUS, &msg_data);
break;
@@ -191,111 +162,129 @@ nserror content_llcache_callback(llcache_handle *llcache,
return error;
}
+
/**
- * Get whether a content can reformat
+ * update content status message
*
- * \param h content to check
- * \return whether the content can reformat
+ * \param c the content to update.
*/
-bool content_can_reformat(hlcache_handle *h)
-{
- struct content *c = hlcache_handle_get_content(h);
-
- if (c == NULL)
- return false;
-
- return (c->handler->reformat != NULL);
-}
-
-
static void content_update_status(struct content *c)
{
if (c->status == CONTENT_STATUS_LOADING ||
- c->status == CONTENT_STATUS_READY) {
+ c->status == CONTENT_STATUS_READY) {
/* Not done yet */
snprintf(c->status_message, sizeof (c->status_message),
- "%s%s%s", messages_get("Fetching"),
- c->sub_status[0] != '\0' ? ", " : " ",
- c->sub_status);
+ "%s%s%s", messages_get("Fetching"),
+ c->sub_status[0] != '\0' ? ", " : " ",
+ c->sub_status);
} else {
snprintf(c->status_message, sizeof (c->status_message),
- "%s (%.1fs)", messages_get("Done"),
- (float) c->time / 1000);
+ "%s (%.1fs)", messages_get("Done"),
+ (float) c->time / 1000);
}
}
-/**
- * Updates content with new status.
- *
- * The textual status contained in the content is updated with given string.
- *
- * \param c The content to set status in.
- * \param status_message new textual status
- */
-
-void content_set_status(struct content *c, const char *status_message)
+/* exported interface documented in content/protected.h */
+nserror
+content__init(struct content *c,
+ const content_handler *handler,
+ lwc_string *imime_type,
+ const struct http_parameter *params,
+ llcache_handle *llcache,
+ const char *fallback_charset,
+ bool quirks)
{
- size_t len = strlen(status_message);
+ struct content_user *user_sentinel;
+ nserror error;
- if (len >= sizeof(c->sub_status)) {
- len = sizeof(c->sub_status) - 1;
+ NSLOG(netsurf, INFO, "url "URL_FMT_SPC" -> %p",
+ nsurl_access_log(llcache_handle_get_url(llcache)), c);
+
+ user_sentinel = calloc(1, sizeof(struct content_user));
+ if (user_sentinel == NULL) {
+ return NSERROR_NOMEM;
}
- memcpy(c->sub_status, status_message, len);
- c->sub_status[len] = '\0';
- content_update_status(c);
-}
+ if (fallback_charset != NULL) {
+ c->fallback_charset = strdup(fallback_charset);
+ if (c->fallback_charset == NULL) {
+ free(user_sentinel);
+ return NSERROR_NOMEM;
+ }
+ }
+ c->llcache = llcache;
+ c->mime_type = lwc_string_ref(imime_type);
+ c->handler = handler;
+ c->status = CONTENT_STATUS_LOADING;
+ c->width = 0;
+ c->height = 0;
+ c->available_width = 0;
+ c->available_height = 0;
+ c->quirks = quirks;
+ c->refresh = 0;
+ nsu_getmonotonic_ms(&c->time);
+ c->size = 0;
+ c->title = NULL;
+ c->active = 0;
+ user_sentinel->callback = NULL;
+ user_sentinel->pw = NULL;
+ user_sentinel->next = NULL;
+ c->user_list = user_sentinel;
+ c->sub_status[0] = 0;
+ c->locked = false;
+ c->total_size = 0;
+ c->http_code = 0;
-/**
- * All data has arrived, convert for display.
- *
- * Calls the convert function for the content.
- *
- * - If the conversion succeeds, but there is still some processing required
- * (eg. loading images), the content gets status CONTENT_STATUS_READY, and a
- * CONTENT_MSG_READY is sent to all users.
- * - If the conversion succeeds and is complete, the content gets status
- * CONTENT_STATUS_DONE, and CONTENT_MSG_READY then CONTENT_MSG_DONE are sent.
- * - If the conversion fails, CONTENT_MSG_ERROR is sent. The content will soon
- * be destroyed and must no longer be used.
- */
+ c->textsearch.string = NULL;
+ c->textsearch.context = NULL;
-void content_convert(struct content *c)
+ content_set_status(c, messages_get("Loading"));
+
+ /* Finally, claim low-level cache events */
+ error = llcache_handle_change_callback(llcache,
+ content_llcache_callback, c);
+ if (error != NSERROR_OK) {
+ lwc_string_unref(c->mime_type);
+ return error;
+ }
+
+ return NSERROR_OK;
+}
+
+
+/* exported interface documented in content/content.h */
+bool content_can_reformat(hlcache_handle *h)
{
- assert(c);
- assert(c->status == CONTENT_STATUS_LOADING ||
- c->status == CONTENT_STATUS_ERROR);
+ struct content *c = hlcache_handle_get_content(h);
- if (c->status != CONTENT_STATUS_LOADING)
- return;
+ if (c == NULL)
+ return false;
- if (c->locked == true)
- return;
-
- NSLOG(netsurf, INFO, "content "URL_FMT_SPC" (%p)",
- nsurl_access_log(llcache_handle_get_url(c->llcache)), c);
+ return (c->handler->reformat != NULL);
+}
- if (c->handler->data_complete != NULL) {
- c->locked = true;
- if (c->handler->data_complete(c) == false) {
- content_set_error(c);
- }
- /* Conversion to the READY state will unlock the content */
- } else {
- content_set_ready(c);
- content_set_done(c);
+
+/* exported interface documented in content/protected.h */
+void content_set_status(struct content *c, const char *status_message)
+{
+ size_t len = strlen(status_message);
+
+ if (len >= sizeof(c->sub_status)) {
+ len = sizeof(c->sub_status) - 1;
}
+ memcpy(c->sub_status, status_message, len);
+ c->sub_status[len] = '\0';
+
+ content_update_status(c);
}
-/**
- * Put a content in status CONTENT_STATUS_READY and unlock the content.
- */
+/* exported interface documented in content/protected.h */
void content_set_ready(struct content *c)
{
- /* The content must be locked at this point, as it can only
+ /* The content must be locked at this point, as it can only
* become READY after conversion. */
assert(c->locked);
c->locked = false;
@@ -305,10 +294,8 @@ void content_set_ready(struct content *c)
content_broadcast(c, CONTENT_MSG_READY, NULL);
}
-/**
- * Put a content in status CONTENT_STATUS_DONE.
- */
+/* exported interface documented in content/protected.h */
void content_set_done(struct content *c)
{
uint64_t now_ms;
@@ -321,38 +308,32 @@ void content_set_done(struct content *c)
content_broadcast(c, CONTENT_MSG_DONE, NULL);
}
-/**
- * Put a content in status CONTENT_STATUS_ERROR and unlock the content.
- *
- * \note We expect the caller to broadcast an error report if needed.
- */
+/* exported interface documented in content/protected.h */
void content_set_error(struct content *c)
{
c->locked = false;
c->status = CONTENT_STATUS_ERROR;
}
-/**
- * Reformat to new size.
- *
- * Calls the reformat function for the content.
- */
+/* exported interface documented in content/content.h */
void content_reformat(hlcache_handle *h, bool background,
- int width, int height)
+ int width, int height)
{
content__reformat(hlcache_handle_get_content(h), background,
- width, height);
+ width, height);
}
-void content__reformat(struct content *c, bool background,
- int width, int height)
+
+/* exported interface documented in content/protected.h */
+void
+content__reformat(struct content *c, bool background, int width, int height)
{
union content_msg_data data;
assert(c != 0);
assert(c->status == CONTENT_STATUS_READY ||
- c->status == CONTENT_STATUS_DONE);
+ c->status == CONTENT_STATUS_DONE);
assert(c->locked == false);
c->available_width = width;
@@ -369,19 +350,14 @@ void content__reformat(struct content *c, bool background,
}
-/**
- * Destroy and free a content.
- *
- * Calls the destroy function for the content, and frees the structure.
- */
-
+/* exported interface documented in content/content.h */
void content_destroy(struct content *c)
{
struct content_rfc5988_link *link;
assert(c);
NSLOG(netsurf, INFO, "content %p %s", c,
- nsurl_access_log(llcache_handle_get_url(c->llcache)));
+ nsurl_access_log(llcache_handle_get_url(c->llcache)));
assert(c->locked == false);
if (c->handler->destroy != NULL)
@@ -417,18 +393,12 @@ void content_destroy(struct content *c)
}
-/**
- * Handle mouse movements in a content window.
- *
- * \param h Content handle
- * \param bw browser window
- * \param mouse state of mouse buttons and modifier keys
- * \param x coordinate of mouse
- * \param y coordinate of mouse
- */
-
-void content_mouse_track(hlcache_handle *h, struct browser_window *bw,
- browser_mouse_state mouse, int x, int y)
+/* exported interface documented in content/content.h */
+void
+content_mouse_track(hlcache_handle *h,
+ struct browser_window *bw,
+ browser_mouse_state mouse,
+ int x, int y)
{
struct content *c = hlcache_handle_get_content(h);
assert(c != NULL);
@@ -446,24 +416,12 @@ void content_mouse_track(hlcache_handle *h, struct browser_window *bw,
}
-/**
- * Handle mouse clicks and movements in a content window.
- *
- * \param h Content handle
- * \param bw browser window
- * \param mouse state of mouse buttons and modifier keys
- * \param x coordinate of mouse
- * \param y coordinate of mouse
- *
- * This function handles both hovering and clicking. It is important that the
- * code path is identical (except that hovering doesn't carry out the action),
- * so that the status bar reflects exactly what will happen. Having separate
- * code paths opens the possibility that an attacker will make the status bar
- * show some harmless action where clicking will be harmful.
- */
-
-void content_mouse_action(hlcache_handle *h, struct browser_window *bw,
- browser_mouse_state mouse, int x, int y)
+/* exported interface documented in content/content.h */
+void
+content_mouse_action(hlcache_handle *h,
+ struct browser_window *bw,
+ browser_mouse_state mouse,
+ int x, int y)
{
struct content *c = hlcache_handle_get_content(h);
assert(c != NULL);
@@ -475,14 +433,7 @@ void content_mouse_action(hlcache_handle *h, struct browser_window *bw,
}
-/**
- * Handle keypresses.
- *
- * \param h Content handle
- * \param key The UCS4 character codepoint
- * \return true if key handled, false otherwise
- */
-
+/* exported interface documented in content/content.h */
bool content_keypress(struct hlcache_handle *h, uint32_t key)
{
struct content *c = hlcache_handle_get_content(h);
@@ -495,34 +446,18 @@ bool content_keypress(struct hlcache_handle *h, uint32_t key)
}
-/**
- * Request a redraw of an area of a content
- *
- * \param h high-level cache handle
- * \param x x co-ord of left edge
- * \param y y co-ord of top edge
- * \param width Width of rectangle
- * \param height Height of rectangle
- */
+/* exported interface documented in content/content.h */
void content_request_redraw(struct hlcache_handle *h,
- int x, int y, int width, int height)
+ int x, int y, int width, int height)
{
content__request_redraw(hlcache_handle_get_content(h),
- x, y, width, height);
+ x, y, width, height);
}
-/**
- * Request a redraw of an area of a content
- *
- * \param c Content
- * \param x x co-ord of left edge
- * \param y y co-ord of top edge
- * \param width Width of rectangle
- * \param height Height of rectangle
- */
+/* exported interface, documented in content/protected.h */
void content__request_redraw(struct content *c,
- int x, int y, int width, int height)
+ int x, int y, int width, int height)
{
union content_msg_data data;
@@ -534,42 +469,96 @@ void content__request_redraw(struct content *c,
data.redraw.width = width;
data.redraw.height = height;
- data.redraw.full_redraw = true;
-
- data.redraw.object = c;
- data.redraw.object_x = 0;
- data.redraw.object_y = 0;
- data.redraw.object_width = c->width;
- data.redraw.object_height = c->height;
-
content_broadcast(c, CONTENT_MSG_REDRAW, &data);
}
+
/* exported interface, documented in content/content.h */
bool content_exec(struct hlcache_handle *h, const char *src, size_t srclen)
{
struct content *c = hlcache_handle_get_content(h);
-
+
assert(c != NULL);
-
+
if (c->locked) {
/* Not safe to do stuff */
NSLOG(netsurf, DEEPDEBUG, "Unable to exec, content locked");
return false;
}
-
+
if (c->handler->exec == NULL) {
/* Can't exec something on this content */
NSLOG(netsurf, DEEPDEBUG, "Unable to exec, no exec function");
return false;
}
-
+
return c->handler->exec(c, src, srclen);
}
+
/* exported interface, documented in content/content.h */
-bool content_redraw(hlcache_handle *h, struct content_redraw_data *data,
- const struct rect *clip, const struct redraw_context *ctx)
+bool content_saw_insecure_objects(struct hlcache_handle *h)
+{
+ struct content *c = hlcache_handle_get_content(h);
+ struct nsurl *url = hlcache_handle_get_url(h);
+ lwc_string *scheme = nsurl_get_component(url, NSURL_SCHEME);
+ bool match;
+
+ /* Is this an internal scheme? If so, we trust here and stop */
+ if ((lwc_string_isequal(scheme, corestring_lwc_about,
+ &match) == lwc_error_ok &&
+ (match == true)) ||
+ (lwc_string_isequal(scheme, corestring_lwc_data,
+ &match) == lwc_error_ok &&
+ (match == true)) ||
+ (lwc_string_isequal(scheme, corestring_lwc_resource,
+ &match) == lwc_error_ok &&
+ (match == true)) ||
+ /* Our internal x-ns-css scheme is secure */
+ (lwc_string_isequal(scheme, corestring_lwc_x_ns_css,
+ &match) == lwc_error_ok &&
+ (match == true)) ||
+ /* We also treat file: as "not insecure" here */
+ (lwc_string_isequal(scheme, corestring_lwc_file,
+ &match) == lwc_error_ok &&
+ (match == true))) {
+ /* No insecurity to find */
+ lwc_string_unref(scheme);
+ return false;
+ }
+
+ /* Okay, not internal, am *I* secure? */
+ if ((lwc_string_isequal(scheme, corestring_lwc_https,
+ &match) == lwc_error_ok)
+ && (match == false)) {
+ /* I did see something insecure -- ME! */
+ lwc_string_unref(scheme);
+ return true;
+ }
+
+ lwc_string_unref(scheme);
+ /* I am supposed to be secure, but was I overridden */
+ if (urldb_get_cert_permissions(url)) {
+ /* I was https:// but I was overridden, that's no good */
+ return true;
+ }
+
+ /* Otherwise try and chain through the handler */
+ if (c != NULL && c->handler->saw_insecure_objects != NULL) {
+ return c->handler->saw_insecure_objects(c);
+ }
+
+ /* If we can't see insecure objects, we can't see them */
+ return false;
+}
+
+
+/* exported interface, documented in content/content.h */
+bool
+content_redraw(hlcache_handle *h,
+ struct content_redraw_data *data,
+ const struct rect *clip,
+ const struct redraw_context *ctx)
{
struct content *c = hlcache_handle_get_content(h);
@@ -590,8 +579,10 @@ bool content_redraw(hlcache_handle *h, struct content_redraw_data *data,
/* exported interface, documented in content/content.h */
-bool content_scaled_redraw(struct hlcache_handle *h,
- int width, int height, const struct redraw_context *ctx)
+bool
+content_scaled_redraw(struct hlcache_handle *h,
+ int width, int height,
+ const struct redraw_context *ctx)
{
struct content *c = hlcache_handle_get_content(h);
struct redraw_context new_ctx = *ctx;
@@ -657,32 +648,22 @@ bool content_scaled_redraw(struct hlcache_handle *h,
return plot_ok;
}
-/**
- * Register a user for callbacks.
- *
- * \param c the content to register
- * \param callback the callback function
- * \param pw callback private data
- * \return true on success, false otherwise on memory exhaustion
- *
- * The callback will be called when content_broadcast() is
- * called with the content.
- */
-bool content_add_user(
- struct content *c,
- void (*callback)(
- struct content *c,
- content_msg msg,
- const union content_msg_data *data,
- void *pw),
- void *pw)
+/* exported interface documented in content/content.h */
+bool
+content_add_user(struct content *c,
+ void (*callback)(
+ struct content *c,
+ content_msg msg,
+ const union content_msg_data *data,
+ void *pw),
+ void *pw)
{
struct content_user *user;
NSLOG(netsurf, INFO, "content "URL_FMT_SPC" (%p), user %p %p",
- nsurl_access_log(llcache_handle_get_url(c->llcache)),
- c, callback, pw);
+ nsurl_access_log(llcache_handle_get_url(c->llcache)),
+ c, callback, pw);
user = malloc(sizeof(struct content_user));
if (!user)
return false;
@@ -698,31 +679,25 @@ bool content_add_user(
}
-/**
- * Remove a callback user.
- *
- * The callback function and pw must be identical to those passed to
- * content_add_user().
- */
-
-void content_remove_user(
- struct content *c,
- void (*callback)(
- struct content *c,
- content_msg msg,
- const union content_msg_data *data,
- void *pw),
- void *pw)
+/* exported interface documented in content/content.h */
+void
+content_remove_user(struct content *c,
+ void (*callback)(
+ struct content *c,
+ content_msg msg,
+ const union content_msg_data *data,
+ void *pw),
+ void *pw)
{
struct content_user *user, *next;
NSLOG(netsurf, INFO, "content "URL_FMT_SPC" (%p), user %p %p",
- nsurl_access_log(llcache_handle_get_url(c->llcache)),
- c, callback, pw);
+ nsurl_access_log(llcache_handle_get_url(c->llcache)),
+ c, callback, pw);
/* user_list starts with a sentinel */
for (user = c->user_list; user->next != 0 &&
- !(user->next->callback == callback &&
- user->next->pw == pw); user = user->next)
+ !(user->next->callback == callback &&
+ user->next->pw == pw); user = user->next)
;
if (user->next == 0) {
NSLOG(netsurf, INFO, "user not found in list");
@@ -738,17 +713,15 @@ void content_remove_user(
free(next);
}
-/**
- * Count users for the content.
- */
+/* exported interface documented in content/content.h */
uint32_t content_count_users(struct content *c)
{
struct content_user *user;
uint32_t counter = 0;
assert(c != NULL);
-
+
for (user = c->user_list; user != NULL; user = user->next)
counter += 1;
@@ -757,13 +730,8 @@ uint32_t content_count_users(struct content *c)
return counter - 1; /* Subtract 1 for the sentinel */
}
-/**
- * Determine if quirks mode matches
- *
- * \param c Content to consider
- * \param quirks Quirks mode to match
- * \return True if quirks match, false otherwise
- */
+
+/* exported interface documented in content/content.h */
bool content_matches_quirks(struct content *c, bool quirks)
{
if (c->handler->matches_quirks == NULL)
@@ -772,23 +740,17 @@ bool content_matches_quirks(struct content *c, bool quirks)
return c->handler->matches_quirks(c, quirks);
}
-/**
- * Determine if a content is shareable
- *
- * \param c Content to consider
- * \return True if content is shareable, false otherwise
- */
+
+/* exported interface documented in content/content.h */
bool content_is_shareable(struct content *c)
{
return c->handler->no_share == false;
}
-/**
- * Send a message to all users.
- */
+/* exported interface documented in content/protected.h */
void content_broadcast(struct content *c, content_msg msg,
- const union content_msg_data *data)
+ const union content_msg_data *data)
{
struct content_user *user, *next;
assert(c);
@@ -801,72 +763,87 @@ void content_broadcast(struct content *c, content_msg msg,
}
}
+
/* exported interface documented in content_protected.h */
-void content_broadcast_errorcode(struct content *c, nserror errorcode)
+void
+content_broadcast_error(struct content *c, nserror errorcode, const char *msg)
{
struct content_user *user, *next;
union content_msg_data data;
assert(c);
- data.errorcode = errorcode;
+ data.errordata.errorcode = errorcode;
+ data.errordata.errormsg = msg;
for (user = c->user_list->next; user != 0; user = next) {
next = user->next; /* user may be destroyed during callback */
if (user->callback != 0) {
- user->callback(c, CONTENT_MSG_ERRORCODE,
- &data, user->pw);
+ user->callback(c, CONTENT_MSG_ERROR,
+ &data, user->pw);
}
}
}
-/**
- * A window containing the content has been opened.
- *
- * \param h handle to content that has been opened
- * \param bw browser window containing the content
- * \param page content of type CONTENT_HTML containing h, or 0 if not an
- * object within a page
- * \param params object parameters, or 0 if not an object
- *
- * Calls the open function for the content.
- */
-
-void content_open(hlcache_handle *h, struct browser_window *bw,
- struct content *page, struct object_params *params)
+/* exported interface, documented in content/content.h */
+nserror
+content_open(hlcache_handle *h,
+ struct browser_window *bw,
+ struct content *page,
+ struct object_params *params)
{
- struct content *c = hlcache_handle_get_content(h);
+ struct content *c;
+ nserror res;
+
+ c = hlcache_handle_get_content(h);
assert(c != 0);
NSLOG(netsurf, INFO, "content %p %s", c,
- nsurl_access_log(llcache_handle_get_url(c->llcache)));
- if (c->handler->open != NULL)
- c->handler->open(c, bw, page, params);
+ nsurl_access_log(llcache_handle_get_url(c->llcache)));
+ if (c->handler->open != NULL) {
+ res = c->handler->open(c, bw, page, params);
+ } else {
+ res = NSERROR_OK;
+ }
+ return res;
}
-/**
- * The window containing the content has been closed.
- *
- * Calls the close function for the content.
- */
-
-void content_close(hlcache_handle *h)
+/* exported interface, documented in content/content.h */
+nserror content_close(hlcache_handle *h)
{
- struct content *c = hlcache_handle_get_content(h);
- assert(c != 0);
+ struct content *c;
+ nserror res;
+
+ c = hlcache_handle_get_content(h);
+ if (c == NULL) {
+ return NSERROR_BAD_PARAMETER;
+ }
+
+ if ((c->status != CONTENT_STATUS_READY) &&
+ (c->status != CONTENT_STATUS_DONE)) {
+ /* status is not read or done so nothing to do */
+ return NSERROR_INVALID;
+ }
+
NSLOG(netsurf, INFO, "content %p %s", c,
- nsurl_access_log(llcache_handle_get_url(c->llcache)));
- if (c->handler->close != NULL)
- c->handler->close(c);
-}
+ nsurl_access_log(llcache_handle_get_url(c->llcache)));
+ if (c->textsearch.context != NULL) {
+ content_textsearch_destroy(c->textsearch.context);
+ c->textsearch.context = NULL;
+ }
-/**
- * Tell a content that any selection it has, or one of its objects has, must be
- * cleared.
- */
+ if (c->handler->close != NULL) {
+ res = c->handler->close(c);
+ } else {
+ res = NSERROR_OK;
+ }
+ return res;
+}
+
+/* exported interface, documented in content/content.h */
void content_clear_selection(hlcache_handle *h)
{
struct content *c = hlcache_handle_get_content(h);
@@ -877,11 +854,7 @@ void content_clear_selection(hlcache_handle *h)
}
-/**
- * Get a text selection from a content. Ownership is passed to the caller,
- * who must free() it.
- */
-
+/* exported interface, documented in content/content.h */
char * content_get_selection(hlcache_handle *h)
{
struct content *c = hlcache_handle_get_content(h);
@@ -893,9 +866,12 @@ char * content_get_selection(hlcache_handle *h)
return NULL;
}
+
/* exported interface documented in content/content.h */
-nserror content_get_contextual_content(struct hlcache_handle *h,
- int x, int y, struct browser_window_features *data)
+nserror
+content_get_contextual_content(struct hlcache_handle *h,
+ int x, int y,
+ struct browser_window_features *data)
{
struct content *c = hlcache_handle_get_content(h);
assert(c != 0);
@@ -909,8 +885,11 @@ nserror content_get_contextual_content(struct hlcache_handle *h,
}
-bool content_scroll_at_point(struct hlcache_handle *h,
- int x, int y, int scrx, int scry)
+/* exported interface, documented in content/content.h */
+bool
+content_scroll_at_point(struct hlcache_handle *h,
+ int x, int y,
+ int scrx, int scry)
{
struct content *c = hlcache_handle_get_content(h);
assert(c != 0);
@@ -922,8 +901,11 @@ bool content_scroll_at_point(struct hlcache_handle *h,
}
-bool content_drop_file_at_point(struct hlcache_handle *h,
- int x, int y, char *file)
+/* exported interface, documented in content/content.h */
+bool
+content_drop_file_at_point(struct hlcache_handle *h,
+ int x, int y,
+ char *file)
{
struct content *c = hlcache_handle_get_content(h);
assert(c != 0);
@@ -935,30 +917,9 @@ bool content_drop_file_at_point(struct hlcache_handle *h,
}
-void content_search(struct hlcache_handle *h, void *context,
- search_flags_t flags, const char *string)
-{
- struct content *c = hlcache_handle_get_content(h);
- assert(c != 0);
-
- if (c->handler->search != NULL) {
- c->handler->search(c, context, flags, string);
- }
-}
-
-
-void content_search_clear(struct hlcache_handle *h)
-{
- struct content *c = hlcache_handle_get_content(h);
- assert(c != 0);
-
- if (c->handler->search_clear != NULL) {
- c->handler->search_clear(c);
- }
-}
-
/* exported interface documented in content/content.h */
-nserror content_debug_dump(struct hlcache_handle *h, FILE *f, enum content_debug op)
+nserror
+content_debug_dump(struct hlcache_handle *h, FILE *f, enum content_debug op)
{
struct content *c = hlcache_handle_get_content(h);
assert(c != 0);
@@ -970,6 +931,7 @@ nserror content_debug_dump(struct hlcache_handle *h, FILE *f, enum content_debug
return c->handler->debug_dump(c, f, op);
}
+
/* exported interface documented in content/content.h */
nserror content_debug(struct hlcache_handle *h, enum content_debug op)
{
@@ -987,12 +949,6 @@ nserror content_debug(struct hlcache_handle *h, enum content_debug op)
}
-void content_add_error(struct content *c, const char *token,
- unsigned int line)
-{
-}
-
-
/* exported interface documented in content/content.h */
struct content_rfc5988_link *
content_find_rfc5988_link(hlcache_handle *h, lwc_string *rel)
@@ -1003,7 +959,7 @@ content_find_rfc5988_link(hlcache_handle *h, lwc_string *rel)
while (link != NULL) {
if (lwc_string_caseless_isequal(link->rel, rel,
- &rel_match) == lwc_error_ok && rel_match) {
+ &rel_match) == lwc_error_ok && rel_match) {
break;
}
link = link->next;
@@ -1011,8 +967,10 @@ content_find_rfc5988_link(hlcache_handle *h, lwc_string *rel)
return link;
}
+
+/* exported interface documented in content/protected.h */
struct content_rfc5988_link *
-content__free_rfc5988_link(struct content_rfc5988_link *link)
+content__free_rfc5988_link(struct content_rfc5988_link *link)
{
struct content_rfc5988_link *next;
@@ -1037,10 +995,13 @@ content__free_rfc5988_link(struct content_rfc5988_link *link)
return next;
}
-bool content__add_rfc5988_link(struct content *c,
- const struct content_rfc5988_link *link)
+
+/* exported interface documented in content/protected.h */
+bool
+content__add_rfc5988_link(struct content *c,
+ const struct content_rfc5988_link *link)
{
- struct content_rfc5988_link *newlink;
+ struct content_rfc5988_link *newlink;
union content_msg_data msg_data;
/* a link relation must be present for it to be a link */
@@ -1055,7 +1016,7 @@ bool content__add_rfc5988_link(struct content *c,
newlink = calloc(1, sizeof(struct content_rfc5988_link));
if (newlink == NULL) {
- return false;
+ return false;
}
/* copy values */
@@ -1086,7 +1047,6 @@ bool content__add_rfc5988_link(struct content *c,
}
-
/* exported interface documented in content/content.h */
nsurl *content_get_url(struct content *c)
{
@@ -1115,6 +1075,7 @@ lwc_string *content_get_mime_type(hlcache_handle *h)
return content__get_mime_type(hlcache_handle_get_content(h));
}
+
/* exported interface documented in content/content_protected.h */
lwc_string *content__get_mime_type(struct content *c)
{
@@ -1147,6 +1108,7 @@ const char *content_get_title(hlcache_handle *h)
return content__get_title(hlcache_handle_get_content(h));
}
+
/* exported interface documented in content/content_protected.h */
const char *content__get_title(struct content *c)
{
@@ -1154,7 +1116,7 @@ const char *content__get_title(struct content *c)
return NULL;
return c->title != NULL ? c->title :
- nsurl_access(llcache_handle_get_url(c->llcache));
+ nsurl_access(llcache_handle_get_url(c->llcache));
}
@@ -1164,6 +1126,7 @@ content_status content_get_status(hlcache_handle *h)
return content__get_status(hlcache_handle_get_content(h));
}
+
/* exported interface documented in content/content_protected.h */
content_status content__get_status(struct content *c)
{
@@ -1180,6 +1143,7 @@ const char *content_get_status_message(hlcache_handle *h)
return content__get_status_message(hlcache_handle_get_content(h));
}
+
/* exported interface documented in content/content_protected.h */
const char *content__get_status_message(struct content *c)
{
@@ -1196,6 +1160,7 @@ int content_get_width(hlcache_handle *h)
return content__get_width(hlcache_handle_get_content(h));
}
+
/* exported interface documented in content/content_protected.h */
int content__get_width(struct content *c)
{
@@ -1212,6 +1177,7 @@ int content_get_height(hlcache_handle *h)
return content__get_height(hlcache_handle_get_content(h));
}
+
/* exported interface documented in content/content_protected.h */
int content__get_height(struct content *c)
{
@@ -1228,6 +1194,7 @@ int content_get_available_width(hlcache_handle *h)
return content__get_available_width(hlcache_handle_get_content(h));
}
+
/* exported interface documented in content/content_protected.h */
int content__get_available_width(struct content *c)
{
@@ -1244,6 +1211,7 @@ const uint8_t *content_get_source_data(hlcache_handle *h, size_t *size)
return content__get_source_data(hlcache_handle_get_content(h), size);
}
+
/* exported interface documented in content/content_protected.h */
const uint8_t *content__get_source_data(struct content *c, size_t *size)
{
@@ -1256,12 +1224,14 @@ const uint8_t *content__get_source_data(struct content *c, size_t *size)
return llcache_handle_get_source_data(c->llcache, size);
}
+
/* exported interface documented in content/content.h */
void content_invalidate_reuse_data(hlcache_handle *h)
{
content__invalidate_reuse_data(hlcache_handle_get_content(h));
}
+
/* exported interface documented in content/content_protected.h */
void content__invalidate_reuse_data(struct content *c)
{
@@ -1272,12 +1242,14 @@ void content__invalidate_reuse_data(struct content *c)
llcache_handle_invalidate_cache_data(c->llcache);
}
+
/* exported interface documented in content/content.h */
nsurl *content_get_refresh_url(hlcache_handle *h)
{
return content__get_refresh_url(hlcache_handle_get_content(h));
}
+
/* exported interface documented in content/content_protected.h */
nsurl *content__get_refresh_url(struct content *c)
{
@@ -1300,9 +1272,9 @@ struct bitmap *content__get_bitmap(struct content *c)
{
struct bitmap *bitmap = NULL;
- if ((c != NULL) &&
- (c->handler != NULL) &&
- (c->handler->type != NULL) &&
+ if ((c != NULL) &&
+ (c->handler != NULL) &&
+ (c->handler->type != NULL) &&
(c->handler->type() == CONTENT_IMAGE) &&
(c->handler->get_internal != NULL) ) {
bitmap = c->handler->get_internal(c, NULL);
@@ -1322,21 +1294,13 @@ bool content_get_opaque(hlcache_handle *h)
/* exported interface documented in content/content_protected.h */
bool content__get_opaque(struct content *c)
{
- bool opaque = false;
-
- if ((c != NULL) &&
- (c->handler != NULL) &&
- (c->handler->type != NULL) &&
- (c->handler->type() == CONTENT_IMAGE) &&
- (c->handler->get_internal != NULL) ) {
- struct bitmap *bitmap = NULL;
- bitmap = c->handler->get_internal(c, NULL);
- if (bitmap != NULL) {
- opaque = guit->bitmap->get_opaque(bitmap);
- }
+ if ((c != NULL) &&
+ (c->handler != NULL) &&
+ (c->handler->is_opaque != NULL)) {
+ return c->handler->is_opaque(c);
}
- return opaque;
+ return false;
}
@@ -1353,14 +1317,16 @@ bool content_get_quirks(hlcache_handle *h)
/* exported interface documented in content/content.h */
-const char *content_get_encoding(hlcache_handle *h, enum content_encoding_type op)
+const char *
+content_get_encoding(hlcache_handle *h, enum content_encoding_type op)
{
return content__get_encoding(hlcache_handle_get_content(h), op);
}
/* exported interface documented in content/content_protected.h */
-const char *content__get_encoding(struct content *c, enum content_encoding_type op)
+const char *
+content__get_encoding(struct content *c, enum content_encoding_type op)
{
const char *encoding = NULL;
@@ -1387,12 +1353,8 @@ bool content__is_locked(struct content *c)
return c->locked;
}
-/**
- * Retrieve the low-level cache handle for a content
- *
- * \param c Content to retrieve from
- * \return Low-level cache handle
- */
+
+/* exported interface documented in content/content.h */
const llcache_handle *content_get_llcache_handle(struct content *c)
{
if (c == NULL)
@@ -1401,12 +1363,8 @@ const llcache_handle *content_get_llcache_handle(struct content *c)
return c->llcache;
}
-/**
- * Clone a content object in its current state.
- *
- * \param c Content to clone
- * \return Clone of \a c
- */
+
+/* exported interface documented in content/protected.h */
struct content *content_clone(struct content *c)
{
struct content *nc;
@@ -1419,13 +1377,8 @@ struct content *content_clone(struct content *c)
return nc;
};
-/**
- * Clone a content's data members
- *
- * \param c Content to clone
- * \param nc Content to populate
- * \return NSERROR_OK on success, appropriate error otherwise
- */
+
+/* exported interface documented in content/protected.h */
nserror content__clone(const struct content *c, struct content *nc)
{
nserror error;
@@ -1486,24 +1439,19 @@ nserror content__clone(const struct content *c, struct content *nc)
nc->locked = c->locked;
nc->total_size = c->total_size;
nc->http_code = c->http_code;
-
+
return NSERROR_OK;
}
-/**
- * Abort a content object
- *
- * \param c The content object to abort
- * \return NSERROR_OK on success, otherwise appropriate error
- */
+
+/* exported interface documented in content/content.h */
nserror content_abort(struct content *c)
{
NSLOG(netsurf, INFO, "Aborting %p", c);
-
+
if (c->handler->stop != NULL)
c->handler->stop(c);
-
+
/* And for now, abort our llcache object */
return llcache_handle_abort(c->llcache);
}
-