summaryrefslogtreecommitdiff
path: root/src/adblock.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/adblock.c')
-rw-r--r--src/adblock.c1451
1 files changed, 768 insertions, 683 deletions
diff --git a/src/adblock.c b/src/adblock.c
index aa6a52b1..e45f6b68 100644
--- a/src/adblock.c
+++ b/src/adblock.c
@@ -29,29 +29,29 @@
/* DECLARATIONS {{{*/
/* Type definitions {{{*/
typedef enum _AdblockOption {
- AO_BEGIN = 1<<2,
- AO_BEGIN_DOMAIN = 1<<3,
- AO_END = 1<<4,
- AO_MATCH_CASE = 1<<7,
- AO_THIRDPARTY = 1<<8,
- AO_NOTHIRDPARTY = 1<<9,
+ AO_BEGIN = 1<<2,
+ AO_BEGIN_DOMAIN = 1<<3,
+ AO_END = 1<<4,
+ AO_MATCH_CASE = 1<<7,
+ AO_THIRDPARTY = 1<<8,
+ AO_NOTHIRDPARTY = 1<<9,
} AdblockOption;
/* Attributes */
typedef enum _AdblockAttribute {
- AA_SCRIPT = 1<<0,
- AA_IMAGE = 1<<1,
- AA_STYLESHEET = 1<<2,
- AA_OBJECT = 1<<3,
- AA_XBL = 1<<4,
- AA_PING = 1<<5,
- AA_XMLHTTPREQUEST = 1<<6,
- AA_OBJECT_SUBREQUEST = 1<<7,
- AA_DTD = 1<<8,
- AA_SUBDOCUMENT = 1<<9,
- AA_DOCUMENT = 1<<10,
- AA_ELEMHIDE = 1<<11,
- AA_OTHER = 1<<12,
- /* inverse */
+ AA_SCRIPT = 1<<0,
+ AA_IMAGE = 1<<1,
+ AA_STYLESHEET = 1<<2,
+ AA_OBJECT = 1<<3,
+ AA_XBL = 1<<4,
+ AA_PING = 1<<5,
+ AA_XMLHTTPREQUEST = 1<<6,
+ AA_OBJECT_SUBREQUEST = 1<<7,
+ AA_DTD = 1<<8,
+ AA_SUBDOCUMENT = 1<<9,
+ AA_DOCUMENT = 1<<10,
+ AA_ELEMHIDE = 1<<11,
+ AA_OTHER = 1<<12,
+ /* inverse */
} AdblockAttribute;
#define AA_CLEAR_FRAME(X) (X & ~(AA_SUBDOCUMENT|AA_DOCUMENT))
@@ -61,91 +61,98 @@ typedef enum _AdblockAttribute {
#define AB_CLEAR_LOWER 0x3fff8000
typedef struct _AdblockRule {
- GRegex *pattern;
- AdblockOption options;
- AdblockAttribute attributes;
- char **domains;
+ GRegex *pattern;
+ AdblockOption options;
+ AdblockAttribute attributes;
+ char **domains;
} AdblockRule;
typedef struct _AdblockElementHider {
- char *selector;
- char **domains;
- gboolean exception;
+ char *selector;
+ char **domains;
+ gboolean exception;
} AdblockElementHider;
/*}}}*/
/* Static variables {{{*/
-static GPtrArray *m_simple_rules;
-static GPtrArray *m_simple_exceptions;
-static GPtrArray *m_rules;
-static GPtrArray *m_exceptions;
-static GHashTable *m_hider_rules;
-gboolean m_has_hider_rules;
+static GPtrArray *s_simple_rules;
+static GPtrArray *s_simple_exceptions;
+static GPtrArray *s_rules;
+static GPtrArray *s_exceptions;
+static GHashTable *s_hider_rules;
+gboolean s_has_hider_rules;
/* only used to freeing elementhider */
-static GSList *m_hider_list;
-static GString *m_css_exceptions;
-static gboolean m_init = false;
-static GSList *m_css_hider_list;
+static GSList *s_hider_list;
+static GString *s_css_exceptions;
+static gboolean s_init = false;
+static GSList *s_css_hider_list;
#define HIDER_LIST_MAX 3000
/*}}}*//*}}}*/
/* NEW AND FREE {{{*/
/* adblock_rule_new {{{*/
static AdblockRule *
-adblock_rule_new() {
- AdblockRule *rule = dwb_malloc(sizeof(AdblockRule));
- rule->pattern = NULL;
- rule->options = 0;
- rule->attributes = 0;
- rule->domains = NULL;
- return rule;
+adblock_rule_new()
+{
+ AdblockRule *rule = dwb_malloc(sizeof(AdblockRule));
+ rule->pattern = NULL;
+ rule->options = 0;
+ rule->attributes = 0;
+ rule->domains = NULL;
+ return rule;
}/*}}}*/
/* adblock_rule_free {{{*/
static void
-adblock_rule_free(AdblockRule *rule) {
- if (rule->pattern != NULL) {
- g_regex_unref(rule->pattern);
- }
- if (rule->domains != NULL) {
- g_strfreev(rule->domains);
- }
- g_free(rule);
+adblock_rule_free(AdblockRule *rule)
+{
+ if (rule->pattern != NULL)
+ g_regex_unref(rule->pattern);
+
+ if (rule->domains != NULL)
+ g_strfreev(rule->domains);
+
+ g_free(rule);
}/*}}}*/
/* adblock_element_hider_new {{{*/
static AdblockElementHider *
-adblock_element_hider_new(const char *selector, char **domains) {
- AdblockElementHider *hider = dwb_malloc(sizeof(AdblockElementHider));
- hider->selector = g_strdup(selector);
- hider->domains = domains;
- return hider;
+adblock_element_hider_new(const char *selector, char **domains)
+{
+ AdblockElementHider *hider = dwb_malloc(sizeof(AdblockElementHider));
+ hider->selector = g_strdup(selector);
+ hider->domains = domains;
+ return hider;
}/*}}}*/
/* adblock_element_hider_free {{{*/
static void
-adblock_element_hider_free(AdblockElementHider *hider) {
- if (hider) {
- if (hider->selector) {
- g_free(hider->selector);
- }
- if (hider->domains) {
- g_strfreev(hider->domains);
+adblock_element_hider_free(AdblockElementHider *hider)
+{
+ if (hider)
+ {
+ if (hider->selector)
+ g_free(hider->selector);
+
+ if (hider->domains)
+ g_strfreev(hider->domains);
+
+ g_free(hider);
}
- g_free(hider);
- }
}/*}}}*//*}}}*/
/* MATCH {{{*/
/* inline adblock_do_match(AdblockRule *, const char *) {{{*/
static inline gboolean
-adblock_do_match(AdblockRule *rule, const char *uri) {
- if (g_regex_match(rule->pattern, uri, 0, NULL)) {
- PRINT_DEBUG("blocked %s %s\n", uri, g_regex_get_pattern(rule->pattern));
- return true;
- }
- return false;
+adblock_do_match(AdblockRule *rule, const char *uri)
+{
+ if (g_regex_match(rule->pattern, uri, 0, NULL))
+ {
+ PRINT_DEBUG("blocked %s %s\n", uri, g_regex_get_pattern(rule->pattern));
+ return true;
+ }
+ return false;
}/*}}}*/
/* adblock_match(GPtrArray *, SoupURI *, const char *base_domain, * AdblockAttribute, gboolean thirdparty) {{{
@@ -159,193 +166,208 @@ adblock_do_match(AdblockRule *rule, const char *uri) {
* thirdparty - thirdparty request ?
* */
gboolean
-adblock_match(GPtrArray *array, const char *uri, const char *uri_host, const char *uri_base, const char *host, const char *domain, AdblockAttribute attributes, gboolean thirdparty) {
- if (array->len == 0)
- return false;
- const char *base_start = strstr(uri, uri_base);
- const char *uri_start = strstr(uri, uri_host);
- const char *suburis[SUBDOMAIN_MAX];
- int uc = 0;
- const char *cur = uri_start;
- const char *nextdot;
- AdblockRule *rule;
- /* Get all suburis */
- suburis[uc++] = cur;
- while (cur != base_start) {
- nextdot = strchr(cur, '.');
- cur = nextdot + 1;
+adblock_match(GPtrArray *array, const char *uri, const char *uri_host, const char *uri_base, const char *host, const char *domain, AdblockAttribute attributes, gboolean thirdparty)
+{
+ if (array->len == 0)
+ return false;
+ const char *base_start = strstr(uri, uri_base);
+ const char *uri_start = strstr(uri, uri_host);
+ const char *suburis[SUBDOMAIN_MAX];
+ int uc = 0;
+ const char *cur = uri_start;
+ const char *nextdot;
+ AdblockRule *rule;
+ /* Get all suburis */
suburis[uc++] = cur;
- if (uc == SUBDOMAIN_MAX-1)
- break;
- }
- suburis[uc++] = NULL;
-
- for (guint i=0; i<array->len; i++) {
- rule = g_ptr_array_index(array, i);
- if ( (attributes & AA_DOCUMENT && !(rule->attributes & AA_DOCUMENT)) || (attributes & AA_SUBDOCUMENT && !(rule->attributes & AA_SUBDOCUMENT)) )
- continue;
- /* If exception attributes exists, check if exception is matched */
- if (AA_CLEAR_FRAME(rule->attributes) & AB_CLEAR_LOWER && (AA_CLEAR_FRAME(rule->attributes) == (AA_CLEAR_FRAME(attributes)<<AB_INVERSE)))
- continue;
- /* If attribute restriction exists, check if attribute is matched */
- if (AA_CLEAR_FRAME(rule->attributes) & AB_CLEAR_UPPER && (AA_CLEAR_FRAME(rule->attributes) != AA_CLEAR_FRAME(attributes))) {
- continue;
- }
- if (rule->domains && !domain_match(rule->domains, host, domain)) {
- continue;
- }
- if ( (rule->options & AO_THIRDPARTY && !thirdparty)
- || (rule->options & AO_NOTHIRDPARTY && thirdparty) )
- continue;
- if (rule->options & AO_BEGIN_DOMAIN) {
- for (int i=0; suburis[i]; i++) {
- if ( adblock_do_match(rule, suburis[i]) )
- return true;
- }
+ while (cur != base_start)
+ {
+ nextdot = strchr(cur, '.');
+ cur = nextdot + 1;
+ suburis[uc++] = cur;
+ if (uc == SUBDOMAIN_MAX-1)
+ break;
}
- else if (adblock_do_match(rule, uri)) {
- return true;
+ suburis[uc++] = NULL;
+
+ for (guint i=0; i<array->len; i++)
+ {
+ rule = g_ptr_array_index(array, i);
+ if ( (attributes & AA_DOCUMENT && !(rule->attributes & AA_DOCUMENT)) || (attributes & AA_SUBDOCUMENT && !(rule->attributes & AA_SUBDOCUMENT)) )
+ continue;
+ /* If exception attributes exists, check if exception is matched */
+ if (AA_CLEAR_FRAME(rule->attributes) & AB_CLEAR_LOWER && (AA_CLEAR_FRAME(rule->attributes) == (AA_CLEAR_FRAME(attributes)<<AB_INVERSE)))
+ continue;
+ /* If attribute restriction exists, check if attribute is matched */
+ if (AA_CLEAR_FRAME(rule->attributes) & AB_CLEAR_UPPER && (AA_CLEAR_FRAME(rule->attributes) != AA_CLEAR_FRAME(attributes)))
+ continue;
+ if (rule->domains && !domain_match(rule->domains, host, domain))
+ continue;
+ if ( (rule->options & AO_THIRDPARTY && !thirdparty)
+ || (rule->options & AO_NOTHIRDPARTY && thirdparty) )
+ continue;
+ if (rule->options & AO_BEGIN_DOMAIN)
+ {
+ for (int i=0; suburis[i]; i++)
+ {
+ if ( adblock_do_match(rule, suburis[i]) )
+ return true;
+ }
+ }
+ else if (adblock_do_match(rule, uri))
+ return true;
}
- }
- return false;
+ return false;
}/*}}}*/
/* adblock_prepare_match (const char *uri, const char *baseURI, AdblockAttribute attributes {{{ */
static gboolean
-adblock_prepare_match(const char *uri, const char *baseURI, AdblockAttribute attributes) {
- char *realuri = NULL;
- SoupURI *suri = NULL, *sbaseuri = NULL;
- gboolean ret = false;
-
- if (! g_regex_match_simple("^https?://", uri, 0, 0)) {
- gboolean last_slash = g_str_has_suffix(baseURI, "/");
- if (*uri == '/' && last_slash)
- realuri = g_strconcat(baseURI, uri+1, NULL);
- else if (*uri != '/' && !last_slash)
- realuri = g_strconcat(baseURI, "/", uri, NULL);
+adblock_prepare_match(const char *uri, const char *baseURI, AdblockAttribute attributes)
+{
+ char *realuri = NULL;
+ SoupURI *suri = NULL, *sbaseuri = NULL;
+ gboolean ret = false;
+
+ if (! g_regex_match_simple("^https?://", uri, 0, 0))
+ {
+ gboolean last_slash = g_str_has_suffix(baseURI, "/");
+ if (*uri == '/' && last_slash)
+ realuri = g_strconcat(baseURI, uri+1, NULL);
+ else if (*uri != '/' && !last_slash)
+ realuri = g_strconcat(baseURI, "/", uri, NULL);
+ else
+ realuri = g_strconcat(baseURI, uri, NULL);
+ }
else
- realuri = g_strconcat(baseURI, uri, NULL);
- }
- else
- realuri = g_strdup(uri);
-
- /* FIXME: soup_uri_get_host is just used to get parse the uri */
- suri = soup_uri_new(realuri);
- if (suri == NULL)
- goto error_out;
- const char *host = soup_uri_get_host(suri);
- if (host == NULL)
- goto error_out;
-
- sbaseuri = soup_uri_new(baseURI);
- if (sbaseuri == NULL)
- goto error_out;
-
- const char *basehost = soup_uri_get_host(sbaseuri);
- if (basehost == NULL)
- goto error_out;
-
- const char *domain = domain_get_base_for_host(host);
- const char *basedomain = domain_get_base_for_host(basehost);
- gboolean thirdparty = g_strcmp0(domain, basedomain);
-
- if (!adblock_match(m_exceptions, realuri, host, domain, basehost, basedomain, attributes, thirdparty)) {
- if (adblock_match(m_rules, realuri, host, domain, basehost, basedomain, attributes, thirdparty)) {
- ret = true;
+ realuri = g_strdup(uri);
+
+ /* FIXME: soup_uri_get_host is just used to get parse the uri */
+ suri = soup_uri_new(realuri);
+ if (suri == NULL)
+ goto error_out;
+ const char *host = soup_uri_get_host(suri);
+ if (host == NULL)
+ goto error_out;
+
+ sbaseuri = soup_uri_new(baseURI);
+ if (sbaseuri == NULL)
+ goto error_out;
+
+ const char *basehost = soup_uri_get_host(sbaseuri);
+ if (basehost == NULL)
+ goto error_out;
+
+ const char *domain = domain_get_base_for_host(host);
+ const char *basedomain = domain_get_base_for_host(basehost);
+ gboolean thirdparty = g_strcmp0(domain, basedomain);
+
+ if (!adblock_match(s_exceptions, realuri, host, domain, basehost, basedomain, attributes, thirdparty))
+ {
+ if (adblock_match(s_rules, realuri, host, domain, basehost, basedomain, attributes, thirdparty))
+ ret = true;
}
- }
error_out:
- if (realuri != NULL) g_free(realuri);
- if (sbaseuri != NULL) soup_uri_free(sbaseuri);
- if (suri != NULL) soup_uri_free(suri);
- return ret;
+ if (realuri != NULL) g_free(realuri);
+ if (sbaseuri != NULL) soup_uri_free(sbaseuri);
+ if (suri != NULL) soup_uri_free(suri);
+ return ret;
}/*}}}*/
/* adblock_apply_element_hider(WebKitWebFrame *frame, GList *gl) {{{*/
void
-adblock_apply_element_hider(WebKitWebFrame *frame, GList *gl) {
- GSList *list;
-
- WebKitWebDataSource *datasource = webkit_web_frame_get_data_source(frame);
- WebKitNetworkRequest *request = webkit_web_data_source_get_request(datasource);
-
- SoupMessage *msg = webkit_network_request_get_message(request);
- if (msg == NULL)
- return;
-
- SoupURI *suri = soup_message_get_first_party(msg);
- g_return_if_fail(suri != NULL);
-
- const char *host = soup_uri_get_host(suri);
- const char *base_domain = domain_get_base_for_host(host);
- g_return_if_fail(host != NULL);
- g_return_if_fail(base_domain != NULL);
-
- AdblockElementHider *hider;
- GString *css_rule = g_string_new(NULL);
-
- /* get all subdomains */
- const char *subdomains[SUBDOMAIN_MAX];
- char *nextdot = NULL;
- int uc = 0;
- const char *tmphost = host;
- subdomains[uc++] = tmphost;
- while (tmphost != base_domain) {
- nextdot = strchr(tmphost, '.');
- tmphost = nextdot + 1;
+adblock_apply_element_hider(WebKitWebFrame *frame, GList *gl)
+{
+ GSList *list;
+
+ WebKitWebDataSource *datasource = webkit_web_frame_get_data_source(frame);
+ WebKitNetworkRequest *request = webkit_web_data_source_get_request(datasource);
+
+ SoupMessage *msg = webkit_network_request_get_message(request);
+ if (msg == NULL)
+ return;
+
+ SoupURI *suri = soup_message_get_first_party(msg);
+ g_return_if_fail(suri != NULL);
+
+ const char *host = soup_uri_get_host(suri);
+ const char *base_domain = domain_get_base_for_host(host);
+ g_return_if_fail(host != NULL);
+ g_return_if_fail(base_domain != NULL);
+
+ AdblockElementHider *hider;
+ GString *css_rule = g_string_new(NULL);
+
+ /* get all subdomains */
+ const char *subdomains[SUBDOMAIN_MAX];
+ char *nextdot = NULL;
+ int uc = 0;
+ const char *tmphost = host;
subdomains[uc++] = tmphost;
- if (uc == SUBDOMAIN_MAX-1)
- break;
- }
- subdomains[uc++] = NULL;
-
- gboolean has_exception = false;
- for (int i=0; subdomains[i]; i++) {
- list = g_hash_table_lookup(m_hider_rules, subdomains[i]);
- if (list) {
- for (GSList *l = list; l; l=l->next) {
- hider = l->data;
- if (hider->exception)
- has_exception = true;
- else if (domain_match(hider->domains, host, base_domain)) {
- g_string_append(css_rule, hider->selector);
- g_string_append_c(css_rule, ',');
+ while (tmphost != base_domain)
+ {
+ nextdot = strchr(tmphost, '.');
+ tmphost = nextdot + 1;
+ subdomains[uc++] = tmphost;
+ if (uc == SUBDOMAIN_MAX-1)
+ break;
+ }
+ subdomains[uc++] = NULL;
+
+ gboolean has_exception = false;
+ for (int i=0; subdomains[i]; i++)
+ {
+ list = g_hash_table_lookup(s_hider_rules, subdomains[i]);
+ if (list)
+ {
+ for (GSList *l = list; l; l=l->next)
+ {
+ hider = l->data;
+ if (hider->exception)
+ has_exception = true;
+ else if (domain_match(hider->domains, host, base_domain))
+ {
+ g_string_append(css_rule, hider->selector);
+ g_string_append_c(css_rule, ',');
+ }
+ }
+ break;
}
- }
- break;
}
- }
- /* Adding replaced exceptions */
- if (! has_exception) {
- g_string_append(css_rule, m_css_exceptions->str);
- }
- if (css_rule->str[css_rule->len-1] == ',')
- g_string_erase(css_rule, css_rule->len-1, 1);
- g_string_append(css_rule, "{display:none!important;}");
- if (frame == webkit_web_view_get_main_frame(WEBVIEW(gl))) {
- WebKitDOMDocument *doc = webkit_web_view_get_dom_document(WEBVIEW(gl));
- WebKitDOMHTMLHeadElement *head = webkit_dom_document_get_head(doc);
+ /* Adding replaced exceptions */
+ if (! has_exception)
+ g_string_append(css_rule, s_css_exceptions->str);
- g_return_if_fail(G_IS_OBJECT(head));
+ if (css_rule->str[css_rule->len-1] == ',')
+ g_string_erase(css_rule, css_rule->len-1, 1);
- for (GSList *l = VIEW(gl)->status->styles; l; l=l->next) {
- webkit_dom_node_append_child(WEBKIT_DOM_NODE(head), WEBKIT_DOM_NODE(l->data), NULL);
- }
- if (css_rule->len > 0) {
- webkit_dom_html_element_set_inner_html(WEBKIT_DOM_HTML_ELEMENT(VIEW(gl)->status->exc_style),
- css_rule->str, NULL);
- webkit_dom_node_append_child(WEBKIT_DOM_NODE(head), WEBKIT_DOM_NODE(VIEW(gl)->status->exc_style), NULL);
+ g_string_append(css_rule, "{display:none!important;}");
+
+ if (frame == webkit_web_view_get_main_frame(WEBVIEW(gl)))
+ {
+ WebKitDOMDocument *doc = webkit_web_view_get_dom_document(WEBVIEW(gl));
+ WebKitDOMHTMLHeadElement *head = webkit_dom_document_get_head(doc);
+
+ g_return_if_fail(G_IS_OBJECT(head));
+
+ for (GSList *l = VIEW(gl)->status->styles; l; l=l->next)
+ webkit_dom_node_append_child(WEBKIT_DOM_NODE(head), WEBKIT_DOM_NODE(l->data), NULL);
+
+ if (css_rule->len > 0)
+ {
+ webkit_dom_html_element_set_inner_html(WEBKIT_DOM_HTML_ELEMENT(VIEW(gl)->status->exc_style),
+ css_rule->str, NULL);
+ webkit_dom_node_append_child(WEBKIT_DOM_NODE(head), WEBKIT_DOM_NODE(VIEW(gl)->status->exc_style), NULL);
+ }
}
- }
- else {
- if (css_rule->len > 0)
+ else
{
- js_call_as_function(frame, VIEW(gl)->js_base, "insertAdblockRule", css_rule->str, kJSTypeString, NULL);
+ if (css_rule->len > 0)
+ {
+ js_call_as_function(frame, VIEW(gl)->js_base, "insertAdblockRule", css_rule->str, kJSTypeString, NULL);
+ }
+ for (GSList *l = s_css_hider_list; l; l=l->next)
+ js_call_as_function(frame, VIEW(gl)->js_base, "insertAdblockRule", l->data, kJSTypeString, NULL);
}
- for (GSList *l = m_css_hider_list; l; l=l->next)
- js_call_as_function(frame, VIEW(gl)->js_base, "insertAdblockRule", l->data, kJSTypeString, NULL);
- }
- g_string_free(css_rule, true);
+ g_string_free(css_rule, true);
}/*}}}*/
/*}}}*/
@@ -354,127 +376,139 @@ adblock_apply_element_hider(WebKitWebFrame *frame, GList *gl) {
/* adblock_before_load_cb (domcallback) {{{*/
static gboolean
-adblock_before_load_cb(WebKitDOMDOMWindow *win, WebKitDOMEvent *event, GList *gl) {
- WebKitDOMElement *src = (void*)webkit_dom_event_get_src_element(event);
- char *tagname = webkit_dom_element_get_tag_name(src);
- const char *url = NULL;
-
- gboolean ret = false;
-
- WebKitDOMDocument *doc = webkit_dom_dom_window_get_document(win);
- char *baseURI = webkit_dom_document_get_document_uri(doc);
-
- WebKitDOMDocument *main_doc = webkit_web_view_get_dom_document(WEBVIEW(gl));
- WebKitDOMDOMWindow *main_win = webkit_dom_document_get_default_view(main_doc);
- AdblockAttribute attributes = win == main_win ? AA_DOCUMENT : AA_SUBDOCUMENT;
-
- if (webkit_dom_element_has_attribute(src, "src"))
- url = webkit_dom_element_get_attribute(src, "src");
- else if (webkit_dom_element_has_attribute(src, "href"))
- url = webkit_dom_element_get_attribute(src, "href");
- else if (webkit_dom_element_has_attribute(src, "data"))
- url = webkit_dom_element_get_attribute(src, "data");
- if (url == NULL)
- goto error_out;
-
- if (!g_strcmp0(tagname, "IMG")) {
- attributes |= AA_IMAGE;
- }
- else if (!g_strcmp0(tagname, "SCRIPT"))
- attributes |= AA_SCRIPT;
- else if (!g_strcmp0(tagname, "LINK") ) {
- char *rel = webkit_dom_html_link_element_get_rel((void*)src);
- char *type = webkit_dom_element_get_attribute(src, "type");
- if (!g_strcmp0(rel, "stylesheet") || !g_strcmp0(type, "text/css")) {
- attributes |= AA_STYLESHEET;
+adblock_before_load_cb(WebKitDOMDOMWindow *win, WebKitDOMEvent *event, GList *gl)
+{
+ WebKitDOMElement *src = (void*)webkit_dom_event_get_src_element(event);
+ char *tagname = webkit_dom_element_get_tag_name(src);
+ const char *url = NULL;
+
+ gboolean ret = false;
+
+ WebKitDOMDocument *doc = webkit_dom_dom_window_get_document(win);
+ char *baseURI = webkit_dom_document_get_document_uri(doc);
+
+ WebKitDOMDocument *main_doc = webkit_web_view_get_dom_document(WEBVIEW(gl));
+ WebKitDOMDOMWindow *main_win = webkit_dom_document_get_default_view(main_doc);
+ AdblockAttribute attributes = win == main_win ? AA_DOCUMENT : AA_SUBDOCUMENT;
+
+ if (webkit_dom_element_has_attribute(src, "src"))
+ url = webkit_dom_element_get_attribute(src, "src");
+ else if (webkit_dom_element_has_attribute(src, "href"))
+ url = webkit_dom_element_get_attribute(src, "href");
+ else if (webkit_dom_element_has_attribute(src, "data"))
+ url = webkit_dom_element_get_attribute(src, "data");
+ if (url == NULL)
+ goto error_out;
+
+ if (!g_strcmp0(tagname, "IMG"))
+ attributes |= AA_IMAGE;
+ else if (!g_strcmp0(tagname, "SCRIPT"))
+ attributes |= AA_SCRIPT;
+ else if (!g_strcmp0(tagname, "LINK") )
+ {
+ char *rel = webkit_dom_html_link_element_get_rel((void*)src);
+ char *type = webkit_dom_element_get_attribute(src, "type");
+ if (!g_strcmp0(rel, "stylesheet") || !g_strcmp0(type, "text/css"))
+ attributes |= AA_STYLESHEET;
+
+ g_free(rel);
+ g_free(type);
}
- g_free(rel);
- g_free(type);
- }
- else if (!g_strcmp0(tagname, "OBJECT") || ! g_strcmp0(tagname, "EMBED")) {
- attributes |= AA_OBJECT;
- }
- if (adblock_prepare_match(url, baseURI, attributes)) {
- webkit_dom_event_prevent_default(event);
- }
- ret = true;
+ else if (!g_strcmp0(tagname, "OBJECT") || ! g_strcmp0(tagname, "EMBED"))
+ attributes |= AA_OBJECT;
+
+ if (adblock_prepare_match(url, baseURI, attributes))
+ webkit_dom_event_prevent_default(event);
+
+ ret = true;
error_out:
- g_object_unref(src);
- g_free(tagname);
- g_free(baseURI);
- return ret;
+ g_object_unref(src);
+ g_free(tagname);
+ g_free(baseURI);
+ return ret;
}/*}}}*/
static void
-adblock_frame_load_status_cb(WebKitWebFrame *frame, GParamSpec *p, GList *gl) {
- WebKitLoadStatus status = webkit_web_frame_get_load_status(frame);
- if (status == WEBKIT_LOAD_FIRST_VISUALLY_NON_EMPTY_LAYOUT) {
- adblock_apply_element_hider(frame, gl);
- }
- else if (status == WEBKIT_LOAD_COMMITTED) {
- dwb_dom_add_frame_listener(frame, "beforeload", G_CALLBACK(adblock_before_load_cb), true, gl);
- }
+adblock_frame_load_status_cb(WebKitWebFrame *frame, GParamSpec *p, GList *gl)
+{
+ WebKitLoadStatus status = webkit_web_frame_get_load_status(frame);
+ if (status == WEBKIT_LOAD_FIRST_VISUALLY_NON_EMPTY_LAYOUT)
+ adblock_apply_element_hider(frame, gl);
+ else if (status == WEBKIT_LOAD_COMMITTED)
+ dwb_dom_add_frame_listener(frame, "beforeload", G_CALLBACK(adblock_before_load_cb), true, gl);
}
/* adblock_frame_created_cb {{{*/
void
-adblock_frame_created_cb(WebKitWebView *wv, WebKitWebFrame *frame, GList *gl) {
- g_signal_connect(frame, "notify::load-status", G_CALLBACK(adblock_frame_load_status_cb), gl);
+adblock_frame_created_cb(WebKitWebView *wv, WebKitWebFrame *frame, GList *gl)
+{
+ g_signal_connect(frame, "notify::load-status", G_CALLBACK(adblock_frame_load_status_cb), gl);
}/*}}}*/
/* adblock_resource_request_cb {{{*/
static void
adblock_resource_request_cb(WebKitWebView *wv, WebKitWebFrame *frame,
WebKitWebResource *resource, WebKitNetworkRequest *request,
- WebKitNetworkResponse *response, GList *gl) {
- if (request == NULL)
- return;
- AdblockAttribute attribute = webkit_web_view_get_main_frame(wv) == frame ? AA_DOCUMENT : AA_SUBDOCUMENT;
-
- const char *uri = webkit_network_request_get_uri(request);
- if (uri == NULL)
- return;
- SoupMessage *msg = webkit_network_request_get_message(request);
- if (msg == NULL)
- return;
- SoupURI *suri = soup_message_get_uri(msg);
- const char *host = soup_uri_get_host(suri);
- if (host == NULL)
- return;
- const char *domain = domain_get_base_for_host(host);
- if (domain == NULL)
- return;
-
- SoupURI *sfirst_party = soup_message_get_first_party(msg);
- if (sfirst_party == NULL)
- return;
- const char *firsthost = soup_uri_get_host(sfirst_party);
- if (firsthost == NULL)
- return;
- const char *firstdomain = domain_get_base_for_host(firsthost);
- if (firstdomain == NULL)
- return;
- gboolean thirdparty = g_strcmp0(domain, firstdomain);
-
- if (!adblock_match(m_simple_exceptions, uri, host, domain, firsthost, firstdomain, attribute, thirdparty)) {
- if (adblock_match(m_simple_rules, uri, host, domain, firsthost, firstdomain, attribute, thirdparty)) {
- webkit_network_request_set_uri(request, "about:blank");
+ WebKitNetworkResponse *response, GList *gl)
+{
+ if (request == NULL)
+ return;
+
+ AdblockAttribute attribute = webkit_web_view_get_main_frame(wv) == frame ? AA_DOCUMENT : AA_SUBDOCUMENT;
+
+ const char *uri = webkit_network_request_get_uri(request);
+ if (uri == NULL)
+ return;
+
+ SoupMessage *msg = webkit_network_request_get_message(request);
+ if (msg == NULL)
+ return;
+
+ SoupURI *suri = soup_message_get_uri(msg);
+ const char *host = soup_uri_get_host(suri);
+ if (host == NULL)
+ return;
+
+ const char *domain = domain_get_base_for_host(host);
+ if (domain == NULL)
+ return;
+
+ SoupURI *sfirst_party = soup_message_get_first_party(msg);
+ if (sfirst_party == NULL)
+ return;
+
+ const char *firsthost = soup_uri_get_host(sfirst_party);
+ if (firsthost == NULL)
+ return;
+
+ const char *firstdomain = domain_get_base_for_host(firsthost);
+ if (firstdomain == NULL)
+ return;
+
+ gboolean thirdparty = g_strcmp0(domain, firstdomain);
+
+ if (!adblock_match(s_simple_exceptions, uri, host, domain, firsthost, firstdomain, attribute, thirdparty))
+ {
+ if (adblock_match(s_simple_rules, uri, host, domain, firsthost, firstdomain, attribute, thirdparty))
+ webkit_network_request_set_uri(request, "about:blank");
}
- }
}/*}}}*/
/* adblock_load_status_cb(WebKitWebView *, GParamSpec *, GList *) {{{*/
static void
-adblock_load_status_cb(WebKitWebView *wv, GParamSpec *p, GList *gl) {
- WebKitLoadStatus status = webkit_web_view_get_load_status(wv);
- if (status == WEBKIT_LOAD_COMMITTED) {
- WebKitDOMDocument *doc = webkit_web_view_get_dom_document(wv);
- WebKitDOMDOMWindow *win = webkit_dom_document_get_default_view(doc);
- webkit_dom_event_target_add_event_listener(WEBKIT_DOM_EVENT_TARGET(win), "beforeload", G_CALLBACK(adblock_before_load_cb), true, gl);
- }
- else if (status == WEBKIT_LOAD_FIRST_VISUALLY_NON_EMPTY_LAYOUT) {
- WebKitWebFrame *frame = webkit_web_view_get_main_frame(wv);
- adblock_apply_element_hider(frame, gl);
- }
+adblock_load_status_cb(WebKitWebView *wv, GParamSpec *p, GList *gl)
+{
+ WebKitLoadStatus status = webkit_web_view_get_load_status(wv);
+ if (status == WEBKIT_LOAD_COMMITTED)
+ {
+ WebKitDOMDocument *doc = webkit_web_view_get_dom_document(wv);
+ WebKitDOMDOMWindow *win = webkit_dom_document_get_default_view(doc);
+ webkit_dom_event_target_add_event_listener(WEBKIT_DOM_EVENT_TARGET(win), "beforeload", G_CALLBACK(adblock_before_load_cb), true, gl);
+ }
+ else if (status == WEBKIT_LOAD_FIRST_VISUALLY_NON_EMPTY_LAYOUT)
+ {
+ WebKitWebFrame *frame = webkit_web_view_get_main_frame(wv);
+ adblock_apply_element_hider(frame, gl);
+ }
}/*}}}*//*}}}*/
@@ -482,381 +516,432 @@ adblock_load_status_cb(WebKitWebView *wv, GParamSpec *p, GList *gl) {
gboolean
adblock_running() {
- return m_init && GET_BOOL("adblocker");
+ return s_init && GET_BOOL("adblocker");
}
/* adblock_disconnect(GList *) {{{*/
void
-adblock_disconnect(GList *gl) {
- View *v = VIEW(gl);
- if (v->status->signals[SIG_AD_LOAD_STATUS] > 0) {
- g_signal_handler_disconnect(WEBVIEW(gl), VIEW(gl)->status->signals[SIG_AD_LOAD_STATUS]);
- v->status->signals[SIG_AD_LOAD_STATUS] = 0;
- }
- if (v->status->signals[SIG_AD_FRAME_CREATED] > 0) {
- g_signal_handler_disconnect(WEBVIEW(gl), (VIEW(gl)->status->signals[SIG_AD_FRAME_CREATED]));
- v->status->signals[SIG_AD_FRAME_CREATED] = 0;
- }
- if (v->status->signals[SIG_AD_RESOURCE_REQUEST] > 0) {
- g_signal_handler_disconnect(WEBVIEW(gl), (VIEW(gl)->status->signals[SIG_AD_RESOURCE_REQUEST]));
- v->status->signals[SIG_AD_RESOURCE_REQUEST] = 0;
- }
+adblock_disconnect(GList *gl)
+{
+ View *v = VIEW(gl);
+ if (v->status->signals[SIG_AD_LOAD_STATUS] > 0)
+ {
+ g_signal_handler_disconnect(WEBVIEW(gl), VIEW(gl)->status->signals[SIG_AD_LOAD_STATUS]);
+ v->status->signals[SIG_AD_LOAD_STATUS] = 0;
+ }
+ if (v->status->signals[SIG_AD_FRAME_CREATED] > 0)
+ {
+ g_signal_handler_disconnect(WEBVIEW(gl), (VIEW(gl)->status->signals[SIG_AD_FRAME_CREATED]));
+ v->status->signals[SIG_AD_FRAME_CREATED] = 0;
+ }
+ if (v->status->signals[SIG_AD_RESOURCE_REQUEST] > 0)
+ {
+ g_signal_handler_disconnect(WEBVIEW(gl), (VIEW(gl)->status->signals[SIG_AD_RESOURCE_REQUEST]));
+ v->status->signals[SIG_AD_RESOURCE_REQUEST] = 0;
+ }
}/*}}}*/
/* adblock_connect() {{{*/
void
-adblock_connect(GList *gl) {
- if (!m_init && !adblock_init())
- return;
- if (m_rules->len > 0 || m_css_hider_list != NULL || m_has_hider_rules) {
- VIEW(gl)->status->signals[SIG_AD_LOAD_STATUS] = g_signal_connect(WEBVIEW(gl), "notify::load-status", G_CALLBACK(adblock_load_status_cb), gl);
- VIEW(gl)->status->signals[SIG_AD_FRAME_CREATED] = g_signal_connect(WEBVIEW(gl), "frame-created", G_CALLBACK(adblock_frame_created_cb), gl);
- }
- if (m_simple_rules->len > 0) {
- VIEW(gl)->status->signals[SIG_AD_RESOURCE_REQUEST] = g_signal_connect(WEBVIEW(gl), "resource-request-starting", G_CALLBACK(adblock_resource_request_cb), gl);
- }
- WebKitDOMDocument *doc = webkit_web_view_get_dom_document(WEBVIEW(gl));
- for (GSList *l = m_css_hider_list; l; l=l->next) {
- WebKitDOMElement *style = webkit_dom_document_create_element(doc, "style", NULL);
- webkit_dom_html_element_set_inner_html(WEBKIT_DOM_HTML_ELEMENT(style), l->data, NULL);
- VIEW(gl)->status->styles = g_slist_prepend(VIEW(gl)->status->styles, style);
- }
- VIEW(gl)->status->exc_style = webkit_dom_document_create_element(doc, "style", NULL);
+adblock_connect(GList *gl)
+{
+ if (!s_init && !adblock_init())
+ return;
+ if (s_rules->len > 0 || s_css_hider_list != NULL || s_has_hider_rules)
+ {
+ VIEW(gl)->status->signals[SIG_AD_LOAD_STATUS] = g_signal_connect(WEBVIEW(gl), "notify::load-status", G_CALLBACK(adblock_load_status_cb), gl);
+ VIEW(gl)->status->signals[SIG_AD_FRAME_CREATED] = g_signal_connect(WEBVIEW(gl), "frame-created", G_CALLBACK(adblock_frame_created_cb), gl);
+ }
+ if (s_simple_rules->len > 0)
+ VIEW(gl)->status->signals[SIG_AD_RESOURCE_REQUEST] = g_signal_connect(WEBVIEW(gl), "resource-request-starting", G_CALLBACK(adblock_resource_request_cb), gl);
+
+ WebKitDOMDocument *doc = webkit_web_view_get_dom_document(WEBVIEW(gl));
+ for (GSList *l = s_css_hider_list; l; l=l->next)
+ {
+ WebKitDOMElement *style = webkit_dom_document_create_element(doc, "style", NULL);
+ webkit_dom_html_element_set_inner_html(WEBKIT_DOM_HTML_ELEMENT(style), l->data, NULL);
+ VIEW(gl)->status->styles = g_slist_prepend(VIEW(gl)->status->styles, style);
+ }
+ VIEW(gl)->status->exc_style = webkit_dom_document_create_element(doc, "style", NULL);
}/*}}}*/
/* adblock_warn_ignored(const char *message, const char *rule){{{*/
static void
-adblock_warn_ignored(const char *message, const char *rule) {
- fprintf(stderr, "Adblock warning: %s\n", message);
- fprintf(stderr, "Adblock warning: Rule %s will be ignored\n", rule);
+adblock_warn_ignored(const char *message, const char *rule)
+{
+ fprintf(stderr, "Adblock warning: %s\n", message);
+ fprintf(stderr, "Adblock warning: Rule %s will be ignored\n", rule);
}/*}}}*/
/* adblock_rule_parse(char *filterlist) {{{*/
static void
-adblock_rule_parse(char *filterlist) {
- char **lines = NULL;
- if (g_file_test(filterlist, G_FILE_TEST_IS_DIR)) {
- GString *string = g_string_new(NULL);
- util_get_directory_content(string, filterlist, NULL);
- if (string->str)
- lines = g_strsplit(string->str, "\n", -1);
- g_string_free(string, true);
- }
- else
- lines = util_get_lines(filterlist);
- if (lines == NULL)
- return;
- char *pattern;
- GError *error = NULL;
- char **domain_arr = NULL;
- char *domains;
- const char *domain;
- const char *tmp;
- const char *option_string;
- const char *o;
- char *tmp_a, *tmp_b, *tmp_c;
- int length = 0;
- int option, attributes, inverse;
- gboolean exception;
- GRegex *rule;
- char **options_arr;
- char warning[256];
- int n_css_rules = 0;
- GString *css_rule = g_string_new(NULL);
- for (int i=0; lines[i] != NULL; i++) {
- pattern = lines[i];
-
- //DwbStatus ret = STATUS_OK;
- GRegexCompileFlags regex_flags = G_REGEX_OPTIMIZE | G_REGEX_CASELESS;
- g_strchomp(pattern);
- util_str_chug(pattern);
- if (*pattern == '\0' || *pattern == '!' || *pattern == '[')
- continue;
-
- tmp_a = tmp_b = tmp_c = NULL;
- /* Element hiding rules */
- if ( (tmp = strstr(pattern, "##")) != NULL) {
- /* Match domains */
- if (*pattern != '#') {
- domains = g_strndup(pattern, tmp-pattern);
- domain_arr = g_strsplit(domains, ",", -1);
-
- AdblockElementHider *hider = adblock_element_hider_new(tmp+2, domain_arr);
- GSList *list;
- gboolean hider_exc = true;
- for (; *domain_arr; domain_arr++) {
- domain = *domain_arr;
- if (*domain == '~')
- domain++;
- else
- hider_exc = false;
- list = g_hash_table_lookup(m_hider_rules, domain);
- if (list == NULL) {
- list = g_slist_append(list, hider);
- g_hash_table_insert(m_hider_rules, g_strdup(domain), list);
- }
- else {
- list = g_slist_append(list, hider);
- (void) list;
- }
- m_has_hider_rules = true;
- }
- hider->exception = hider_exc;
- if (hider_exc) {
- g_string_append(m_css_exceptions, tmp + 2);
- g_string_append_c(m_css_exceptions, ',');
- }
- m_hider_list = g_slist_append(m_hider_list, hider);
- g_free(domains);
- }
- /* general rules */
- else {
- g_string_append(css_rule, tmp+2);
- n_css_rules++;
- if (n_css_rules == HIDER_LIST_MAX)
+adblock_rule_parse(char *filterlist)
+{
+ char **lines = NULL;
+ if (g_file_test(filterlist, G_FILE_TEST_IS_DIR))
+ {
+ GString *string = g_string_new(NULL);
+ util_get_directory_content(string, filterlist, NULL);
+ if (string->str)
+ lines = g_strsplit(string->str, "\n", -1);
+
+ g_string_free(string, true);
+ }
+ else
+ lines = util_get_lines(filterlist);
+
+ if (lines == NULL)
+ return;
+
+ char *pattern;
+ GError *error = NULL;
+ char **domain_arr = NULL;
+ char *domains;
+ const char *domain;
+ const char *tmp;
+ const char *option_string;
+ const char *o;
+ char *tmp_a, *tmp_b, *tmp_c;
+ int length = 0;
+ int option, attributes, inverse;
+ gboolean exception;
+ GRegex *rule;
+ char **options_arr;
+ char warning[256];
+ int n_css_rules = 0;
+ GString *css_rule = g_string_new(NULL);
+
+ for (int i=0; lines[i] != NULL; i++)
+ {
+ pattern = lines[i];
+
+ //DwbStatus ret = STATUS_OK;
+ GRegexCompileFlags regex_flags = G_REGEX_OPTIMIZE | G_REGEX_CASELESS;
+ g_strchomp(pattern);
+ util_str_chug(pattern);
+ if (*pattern == '\0' || *pattern == '!' || *pattern == '[')
+ continue;
+
+ tmp_a = tmp_b = tmp_c = NULL;
+ /* Element hiding rules */
+ if ( (tmp = strstr(pattern, "##")) != NULL)
{
- g_string_append(css_rule, "{display:none!important;}");
- m_css_hider_list = g_slist_prepend(m_css_hider_list, css_rule->str);
- n_css_rules = 0;
- g_string_free(css_rule, false);
- css_rule = g_string_new(NULL);
- }
- else {
- g_string_append_c(css_rule, ',');
+ /* Match domains */
+ if (*pattern != '#')
+ {
+ domains = g_strndup(pattern, tmp-pattern);
+ domain_arr = g_strsplit(domains, ",", -1);
+
+ AdblockElementHider *hider = adblock_element_hider_new(tmp+2, domain_arr);
+ GSList *list;
+ gboolean hider_exc = true;
+ for (; *domain_arr; domain_arr++)
+ {
+ domain = *domain_arr;
+ if (*domain == '~')
+ domain++;
+ else
+ hider_exc = false;
+ list = g_hash_table_lookup(s_hider_rules, domain);
+ if (list == NULL)
+ {
+ list = g_slist_append(list, hider);
+ g_hash_table_insert(s_hider_rules, g_strdup(domain), list);
+ }
+ else
+ {
+ list = g_slist_append(list, hider);
+ (void) list;
+ }
+ s_has_hider_rules = true;
+ }
+ hider->exception = hider_exc;
+ if (hider_exc)
+ {
+ g_string_append(s_css_exceptions, tmp + 2);
+ g_string_append_c(s_css_exceptions, ',');
+ }
+ s_hider_list = g_slist_append(s_hider_list, hider);
+ g_free(domains);
+ }
+ /* general rules */
+ else
+ {
+ g_string_append(css_rule, tmp+2);
+ n_css_rules++;
+ if (n_css_rules == HIDER_LIST_MAX)
+ {
+ g_string_append(css_rule, "{display:none!important;}");
+ s_css_hider_list = g_slist_prepend(s_css_hider_list, css_rule->str);
+ n_css_rules = 0;
+ g_string_free(css_rule, false);
+ css_rule = g_string_new(NULL);
+ }
+ else
+ g_string_append_c(css_rule, ',');
+ }
}
- }
- }
- /* Request patterns */
- else {
- exception = false;
- option = 0;
- attributes = 0;
- rule = NULL;
- domain_arr = NULL;
- /* Exception */
- tmp = pattern;
- if (tmp[0] == '@' && tmp[1] == '@') {
- exception = true;
- tmp +=2;
- }
- option_string = strstr(tmp, "$");
- if (option_string != NULL) {
- tmp_a = g_strndup(tmp, option_string - tmp);
- options_arr = g_strsplit(option_string+1, ",", -1);
- for (int i=0; options_arr[i] != NULL; i++) {
- inverse = 0;
- o = options_arr[i];
- /* attributes */
- if (*o == '~') {
- inverse = AB_INVERSE;
- o++;
- }
- if (!g_strcmp0(o, "script"))
- attributes |= (AA_SCRIPT << inverse);
- else if (!g_strcmp0(o, "image"))
- attributes |= (AA_IMAGE << inverse);
- else if (!g_strcmp0(o, "stylesheet"))
- attributes |= (AA_STYLESHEET << inverse);
- else if (!g_strcmp0(o, "object")) {
- attributes |= (AA_OBJECT << inverse);
- }
- else if (!g_strcmp0(o, "subdocument")) {
- attributes |= inverse ? AA_DOCUMENT : AA_SUBDOCUMENT;
- }
- else if (!g_strcmp0(o, "document")) {
- if (exception)
- attributes |= inverse ? AA_DOCUMENT : AA_SUBDOCUMENT;
+ /* Request patterns */
+ else
+ {
+ exception = false;
+ option = 0;
+ attributes = 0;
+ rule = NULL;
+ domain_arr = NULL;
+ /* Exception */
+ tmp = pattern;
+ if (tmp[0] == '@' && tmp[1] == '@')
+ {
+ exception = true;
+ tmp +=2;
+ }
+ option_string = strstr(tmp, "$");
+ if (option_string != NULL)
+ {
+ tmp_a = g_strndup(tmp, option_string - tmp);
+ options_arr = g_strsplit(option_string+1, ",", -1);
+ for (int i=0; options_arr[i] != NULL; i++)
+ {
+ inverse = 0;
+ o = options_arr[i];
+ /* attributes */
+ if (*o == '~')
+ {
+ inverse = AB_INVERSE;
+ o++;
+ }
+ if (!g_strcmp0(o, "script"))
+ attributes |= (AA_SCRIPT << inverse);
+ else if (!g_strcmp0(o, "image"))
+ attributes |= (AA_IMAGE << inverse);
+ else if (!g_strcmp0(o, "stylesheet"))
+ attributes |= (AA_STYLESHEET << inverse);
+ else if (!g_strcmp0(o, "object"))
+ attributes |= (AA_OBJECT << inverse);
+ else if (!g_strcmp0(o, "subdocument"))
+ attributes |= inverse ? AA_DOCUMENT : AA_SUBDOCUMENT;
+ else if (!g_strcmp0(o, "document"))
+ {
+ if (exception)
+ attributes |= inverse ? AA_DOCUMENT : AA_SUBDOCUMENT;
+ else
+ adblock_warn_ignored("Adblock option 'document' can only be applied to exception rules", pattern);
+ }
+ else if (!g_strcmp0(o, "match-case"))
+ option |= AO_MATCH_CASE;
+ else if (!g_strcmp0(o, "third-party"))
+ {
+ if (inverse)
+ option |= AO_NOTHIRDPARTY;
+ else
+ option |= AO_THIRDPARTY;
+ }
+ else if (g_str_has_prefix(o, "domain="))
+ domain_arr = g_strsplit(options_arr[i] + 7, "|", -1);
+ /* Unsupported should only be ignored if they are actually rules, not
+ * exceptions */
+ else if ((inverse && exception) || (!inverse && !exception))
+ {
+ /* currently unsupported xbl, ping, xmlhttprequest, dtd, elemhide,
+ * other, collapse, donottrack, object-subrequest, popup
+ * */
+ snprintf(warning, sizeof(warning), "Adblock option '%s' isn't supported", o);
+ adblock_warn_ignored(warning, pattern);
+ goto error_out;
+ }
+ }
+ tmp = tmp_a;
+ g_strfreev(options_arr);
+ }
+ length = strlen(tmp);
+ /* Beginning of pattern / domain */
+ if (length > 0 && tmp[0] == '|')
+ {
+ if (length > 1 && tmp[1] == '|')
+ {
+ option |= AO_BEGIN_DOMAIN;
+ tmp += 2;
+ length -= 2;
+ }
+ else
+ {
+ option |= AO_BEGIN;
+ tmp++;
+ length--;
+ }
+ }
+ /* End of pattern */
+ if (length > 0 && tmp[length-1] == '|')
+ {
+ tmp_b = g_strndup(tmp, length-1);
+ tmp = tmp_b;
+ option |= AO_END;
+ length--;
+ }
+ /* Regular Expression */
+ if (length > 0 && tmp[0] == '/' && tmp[length-1] == '/')
+ {
+ tmp_c = g_strndup(tmp+1, length-2);
+
+ if ( (option & AO_MATCH_CASE) != 0)
+ regex_flags &= ~G_REGEX_CASELESS;
+ rule = g_regex_new(tmp_c, regex_flags, 0, &error);
+
+ g_free(tmp_c);
+ if (error != NULL)
+ {
+ adblock_warn_ignored("Invalid regular expression", pattern);
+ //ret = STATUS_ERROR;
+ g_clear_error(&error);
+ goto error_out;
+ }
+ }
else
- adblock_warn_ignored("Adblock option 'document' can only be applied to exception rules", pattern);
- }
- else if (!g_strcmp0(o, "match-case"))
- option |= AO_MATCH_CASE;
- else if (!g_strcmp0(o, "third-party")) {
- if (inverse) {
- option |= AO_NOTHIRDPARTY;
+ {
+ GString *buffer = g_string_new(NULL);
+ if (option & AO_BEGIN || option & AO_BEGIN_DOMAIN)
+ g_string_append_c(buffer, '^');
+
+ /* FIXME: possibly use g_regex_escape_string */
+ for (const char *regexp_tmp = tmp; *regexp_tmp; regexp_tmp++ )
+ {
+ switch (*regexp_tmp) {
+ case '^' : g_string_append(buffer, "([\\x00-\\x24\\x26-\\x2C\\x2F\\x3A-\\x40\\x5B-\\x5E\\x60\\x7B-\\x80]|$)");
+ break;
+ case '*' : g_string_append(buffer, ".*");
+ break;
+ case '?' :
+ case '{' :
+ case '}' :
+ case '(' :
+ case ')' :
+ case '[' :
+ case ']' :
+ case '+' :
+ case '.' :
+ case '\\' :
+ case '|' : g_string_append_c(buffer, '\\');
+ default : g_string_append_c(buffer, *regexp_tmp);
+ }
+ }
+ if (option & AO_END)
+ g_string_append_c(buffer, '$');
+
+ if ( (option & AO_MATCH_CASE) != 0)
+ regex_flags &= ~G_REGEX_CASELESS;
+
+ rule = g_regex_new(buffer->str, regex_flags, 0, &error);
+
+ g_string_free(buffer, true);
+
+ if (error != NULL)
+ {
+ fprintf(stderr, "dwb warning: ignoring adblock rule %s: %s\n", pattern, error->message);
+ g_clear_error(&error);
+ goto error_out;
+ }
}
- else {
- option |= AO_THIRDPARTY;
+
+ AdblockRule *adrule = adblock_rule_new();
+ adrule->attributes = attributes;
+ adrule->pattern = rule;
+ adrule->options = option;
+ adrule->domains = domain_arr;
+
+ if (! (attributes & (AA_DOCUMENT | AA_SUBDOCUMENT)) )
+ adrule->attributes |= AA_SUBDOCUMENT | AA_DOCUMENT;
+
+ if (!(attributes & ~(AA_SUBDOCUMENT | AA_DOCUMENT)))
+ {
+ if (exception)
+ g_ptr_array_add(s_simple_exceptions, adrule);
+ else
+ g_ptr_array_add(s_simple_rules, adrule);
+ }
+ else
+ {
+ if (exception)
+ g_ptr_array_add(s_exceptions, adrule);
+ else
+ g_ptr_array_add(s_rules, adrule);
}
- }
- else if (g_str_has_prefix(o, "domain=")) {
- domain_arr = g_strsplit(options_arr[i] + 7, "|", -1);
- }
- /* Unsupported should only be ignored if they are actually rules, not
- * exceptions */
- else if ((inverse && exception) || (!inverse && !exception)) {
- /* currently unsupported xbl, ping, xmlhttprequest, dtd, elemhide,
- * other, collapse, donottrack, object-subrequest, popup
- * */
- snprintf(warning, sizeof(warning), "Adblock option '%s' isn't supported", o);
- adblock_warn_ignored(warning, pattern);
- goto error_out;
- }
- }
- tmp = tmp_a;
- g_strfreev(options_arr);
- }
- length = strlen(tmp);
- /* Beginning of pattern / domain */
- if (length > 0 && tmp[0] == '|') {
- if (length > 1 && tmp[1] == '|') {
- option |= AO_BEGIN_DOMAIN;
- tmp += 2;
- length -= 2;
- }
- else {
- option |= AO_BEGIN;
- tmp++;
- length--;
- }
- }
- /* End of pattern */
- if (length > 0 && tmp[length-1] == '|') {
- tmp_b = g_strndup(tmp, length-1);
- tmp = tmp_b;
- option |= AO_END;
- length--;
- }
- /* Regular Expression */
- if (length > 0 && tmp[0] == '/' && tmp[length-1] == '/') {
- tmp_c = g_strndup(tmp+1, length-2);
-
- if ( (option & AO_MATCH_CASE) != 0)
- regex_flags &= ~G_REGEX_CASELESS;
- rule = g_regex_new(tmp_c, regex_flags, 0, &error);
-
- g_free(tmp_c);
- if (error != NULL) {
- adblock_warn_ignored("Invalid regular expression", pattern);
- //ret = STATUS_ERROR;
- g_clear_error(&error);
- goto error_out;
- }
- }
- else {
- GString *buffer = g_string_new(NULL);
- if (option & AO_BEGIN || option & AO_BEGIN_DOMAIN) {
- g_string_append_c(buffer, '^');
- }
- /* FIXME: possibly use g_regex_escape_string */
- for (const char *regexp_tmp = tmp; *regexp_tmp; regexp_tmp++ ) {
- switch (*regexp_tmp) {
- case '^' : g_string_append(buffer, "([\\x00-\\x24\\x26-\\x2C\\x2F\\x3A-\\x40\\x5B-\\x5E\\x60\\x7B-\\x80]|$)");
- break;
- case '*' : g_string_append(buffer, ".*");
- break;
- case '?' :
- case '{' :
- case '}' :
- case '(' :
- case ')' :
- case '[' :
- case ']' :
- case '+' :
- case '.' :
- case '\\' :
- case '|' : g_string_append_c(buffer, '\\');
- default : g_string_append_c(buffer, *regexp_tmp);
- }
- }
- if (option & AO_END) {
- g_string_append_c(buffer, '$');
- }
- if ( (option & AO_MATCH_CASE) != 0)
- regex_flags &= ~G_REGEX_CASELESS;
- rule = g_regex_new(buffer->str, regex_flags, 0, &error);
- g_string_free(buffer, true);
- if (error != NULL) {
- fprintf(stderr, "dwb warning: ignoring adblock rule %s: %s\n", pattern, error->message);
- g_clear_error(&error);
- goto error_out;
}
- }
- AdblockRule *adrule = adblock_rule_new();
- adrule->attributes = attributes;
- adrule->pattern = rule;
- adrule->options = option;
- adrule->domains = domain_arr;
-
- if (! (attributes & (AA_DOCUMENT | AA_SUBDOCUMENT)) )
- adrule->attributes |= AA_SUBDOCUMENT | AA_DOCUMENT;
-
- if (!(attributes & ~(AA_SUBDOCUMENT | AA_DOCUMENT))) {
- if (exception)
- g_ptr_array_add(m_simple_exceptions, adrule);
- else
- g_ptr_array_add(m_simple_rules, adrule);
- }
- else {
- if (exception)
- g_ptr_array_add(m_exceptions, adrule);
- else
- g_ptr_array_add(m_rules, adrule);
- }
- }
error_out:
- g_free(tmp_a);
- g_free(tmp_b);
- }
- if (css_rule->len > 0) {
- g_string_erase(css_rule, css_rule->len-1, 1);
- g_string_append(css_rule, "{display:none!important;}");
- m_css_hider_list = g_slist_prepend(m_css_hider_list, css_rule->str);
- }
- g_string_free(css_rule, false);
- g_strfreev(lines);
+ g_free(tmp_a);
+ g_free(tmp_b);
+ }
+ if (css_rule->len > 0)
+ {
+ g_string_erase(css_rule, css_rule->len-1, 1);
+ g_string_append(css_rule, "{display:none!important;}");
+ s_css_hider_list = g_slist_prepend(s_css_hider_list, css_rule->str);
+ }
+ g_string_free(css_rule, false);
+ g_strfreev(lines);
}/*}}}*/
/* adblock_end() {{{*/
void
-adblock_end() {
- for (GSList *l = m_css_hider_list; l; l=l->next) {
- g_free(l->data);
- }
- g_slist_free(m_css_hider_list);
- if (m_css_exceptions != NULL)
- g_string_free(m_css_exceptions, true);
- if (m_rules != NULL)
- g_ptr_array_free(m_rules, true);
- if (m_simple_rules != NULL)
- g_ptr_array_free(m_simple_rules, true);
- if (m_simple_exceptions != NULL)
- g_ptr_array_free(m_simple_exceptions, true);
- if(m_exceptions != NULL)
- g_ptr_array_free(m_exceptions, true);
- if (m_hider_rules != NULL)
- g_hash_table_remove_all(m_hider_rules);
- if (m_hider_list != NULL) {
- for (GSList *l = m_hider_list; l; l=l->next)
- adblock_element_hider_free((AdblockElementHider*)l->data);
- g_slist_free(m_hider_list);
- }
+adblock_end()
+{
+ for (GSList *l = s_css_hider_list; l; l=l->next)
+ g_free(l->data);
+
+ g_slist_free(s_css_hider_list);
+ if (s_css_exceptions != NULL)
+ g_string_free(s_css_exceptions, true);
+ if (s_rules != NULL)
+ g_ptr_array_free(s_rules, true);
+ if (s_simple_rules != NULL)
+ g_ptr_array_free(s_simple_rules, true);
+ if (s_simple_exceptions != NULL)
+ g_ptr_array_free(s_simple_exceptions, true);
+ if(s_exceptions != NULL)
+ g_ptr_array_free(s_exceptions, true);
+ if (s_hider_rules != NULL)
+ g_hash_table_remove_all(s_hider_rules);
+ if (s_hider_list != NULL)
+ {
+ for (GSList *l = s_hider_list; l; l=l->next)
+ adblock_element_hider_free((AdblockElementHider*)l->data);
+
+ g_slist_free(s_hider_list);
+ }
}/*}}}*/
/* adblock_init() {{{*/
gboolean
-adblock_init() {
- if (m_init)
+adblock_init()
+{
+ if (s_init)
+ return true;
+ if (!GET_BOOL("adblocker"))
+ return false;
+
+ char *filterlist = GET_CHAR("adblocker-filterlist");
+ if (filterlist == NULL)
+ return false;
+
+ char buffer[PATH_MAX];
+
+ filterlist = util_expand_home(buffer, filterlist, sizeof(buffer));
+ if (!g_file_test(filterlist, G_FILE_TEST_EXISTS))
+ {
+ fprintf(stderr, "Filterlist not found: %s\n", filterlist);
+ return false;
+ }
+
+ s_rules = g_ptr_array_new_with_free_func((GDestroyNotify)adblock_rule_free);
+ s_exceptions = g_ptr_array_new_with_free_func((GDestroyNotify)adblock_rule_free);
+ s_simple_rules = g_ptr_array_new_with_free_func((GDestroyNotify)adblock_rule_free);
+ s_simple_exceptions = g_ptr_array_new_with_free_func((GDestroyNotify)adblock_rule_free);
+ s_hider_rules = g_hash_table_new_full((GHashFunc)g_str_hash, (GEqualFunc)g_str_equal, (GDestroyNotify)g_free, NULL);
+ s_css_exceptions = g_string_new(NULL);
+
+ adblock_rule_parse(filterlist);
+ s_init = true;
+
return true;
- if (!GET_BOOL("adblocker"))
- return false;
- char *filterlist = GET_CHAR("adblocker-filterlist");
- if (filterlist == NULL)
- return false;
- char buffer[PATH_MAX];
- filterlist = util_expand_home(buffer, filterlist, sizeof(buffer));
- if (!g_file_test(filterlist, G_FILE_TEST_EXISTS)) {
- fprintf(stderr, "Filterlist not found: %s\n", filterlist);
- return false;
- }
- m_rules = g_ptr_array_new_with_free_func((GDestroyNotify)adblock_rule_free);
- m_exceptions = g_ptr_array_new_with_free_func((GDestroyNotify)adblock_rule_free);
- m_simple_rules = g_ptr_array_new_with_free_func((GDestroyNotify)adblock_rule_free);
- m_simple_exceptions = g_ptr_array_new_with_free_func((GDestroyNotify)adblock_rule_free);
- m_hider_rules = g_hash_table_new_full((GHashFunc)g_str_hash, (GEqualFunc)g_str_equal, (GDestroyNotify)g_free, NULL);
- m_css_exceptions = g_string_new(NULL);
- adblock_rule_parse(filterlist);
- m_init = true;
- return true;
}/*}}}*//*}}}*/