Project

General

Profile

« Previous | Next » 

Revision 830d22d8

Added by koszko over 1 year ago

support Parabola's Iceweasel in tests

View differences:

configure
91 91
    elif [ "x$TARGET" = xlibrewolf ]; then
92 92
	# Debian's path to Librewolf
93 93
	BROWSER_BINARY=/usr/share/librewolf/librewolf
94
    elif [ "x$TARGET" = xiceweasel ]; then
95
	# Parabola's path to Iceweasel
96
	BROWSER_BINARY=/usr/lib/iceweasel/iceweasel
94 97
    elif [ "x$TARGET" = xicecat ]; then
95 98
	# Parabola's path to IceCat
96 99
	BROWSER_BINARY=/usr/lib/icecat/icecat
content/policy_enforcing.js
159 159
    delete script.haketilo_blocked_type;
160 160
}
161 161

  
162
/*
163
 * Blocking certain attributes that might allow 'javascript:' URLs. Some of
164
 * these are: <iframe>'s 'src' attributes (would normally execute js in URL upon
165
 * frame's load), <object>'s 'data' attribute (would also execute upon load) and
166
 * <a>'s 'href' attribute (would execute upon link click).
167
 */
162 168
const bad_url_reg = /^data:([^,;]*ml|unknown-content-type)|^javascript:/i;
163 169
function sanitize_element_urls(element) {
164 170
    if (element.haketilo_sanitized_urls)
......
166 172

  
167 173
    element.haketilo_sanitized_urls = true;
168 174

  
175
    let some_attr_blocked = false;
176

  
169 177
    for (const attr of [...element.attributes || []]
170 178
	       .filter(attr => /^(href|src|data)$/i.test(attr.localName))
171 179
	       .filter(attr => bad_url_reg.test(attr.value))) {
180
	/*
181
	 * Under some browsers (Mozilla) removing attributes doesn't stop their
182
	 * javascript from executing, but replacing them does. For 'src' and
183
	 * 'data' I chose to replace the attribute with a 'data:' URL and have
184
	 * it replace bad <iframe>'s/<object>'s contents with a "blocked"
185
	 * string. For 'href' (which appears on <a>'s) I chose to use a
186
	 * 'javascript:' URL to avoid having the page reloaded upon a link
187
	 * click.
188
	 */
172 189
	const replacement_value = /^href$/i.test(attr.localName) ?
173
	      "javascript:void('blocked');" : "data:text/plain,blocked";
190
              "javascript:void('blocked');" : "data:text/plain,blocked";
191
	some_attr_blocked = true;
174 192
	block_attribute(element, attr.localName, attr.namespaceURI,
175
		       replacement_value);
193
			replacement_value);
194
    }
195

  
196
    /*
197
     * Trial and error shows that under certain browsers additional element
198
     * removal and re-addition might be necessary to prevent execution of a
199
     * 'javascript:' URL (Parabola's Iceweasel 75 requires it for 'src' URL of
200
     * an <iframe>).
201
     */
202
    if (some_attr_blocked) {
203
	const replacement_elem = document.createElement("a");
204
	element.replaceWith(replacement_elem);
205
	replacement_elem.replaceWith(element);
176 206
    }
177 207
}
178 208

  
......
189 219
	    continue;
190 220

  
191 221
	/*
192
	 * Guard against redefined getter on DOM object property. This should
193
	 * not be an issue  */
222
	 * Guard against redefined getter on DOM object property. This is a
223
	 * supplemental security measure since page's own scripts should be
224
	 * blocked and unable to redefine properties, anyway.
225
	 */
194 226
	if (Object.getOwnPropertyDescriptor(element.wrappedJSObject, attr)) {
195 227
	    console.error("Redefined property on a DOM object! The page might have bypassed our script blocking measures!");
196 228
	    continue;
pytest.ini
17 17
markers =
18 18
    ext_data: define a custom testing extension for `webextension` fixture.
19 19
    get_page: define a url the `driver` fixture should navigate the browser to.
20
    second_driver: tell `driver` fixture to spawn a separate browser instance fr this test.
test/conftest.py
59 59
@pytest.fixture()
60 60
def driver(_driver, request):
61 61
    nav_target = request.node.get_closest_marker('get_page')
62
    close_all_but_one_window(_driver)
63
    _driver.get(nav_target.args[0] if nav_target else 'about:blank')
64
    _driver.implicitly_wait(0)
65
    yield _driver
62
    nav_target = nav_target.args[0] if nav_target else 'about:blank'
63

  
64
    second_driver = request.node.get_closest_marker('second_driver')
65

  
66
    if second_driver:
67
        with firefox_safe_mode() as _driver:
68
            _driver.get(nav_target)
69
            yield _driver
70
            _driver.quit()
71
    else:
72
        close_all_but_one_window(_driver)
73
        _driver.get(nav_target)
74
        _driver.implicitly_wait(0)
75
        yield _driver
66 76

  
67 77
@pytest.fixture()
68 78
def webextension(driver, request):
......
87 97

  
88 98
    yield
89 99

  
90
    close_all_but_one_window(driver)
91
    driver.get('https://gotmyowndoma.in/')
100
    # Unloading an extension might cause its windows to vanish. Make sure
101
    # there's at least one window navigated to some other page before
102
    # uninstalling the addon. Otherwise, we could be left with a windowless
103
    # browser :c
104
    driver.switch_to.window(driver.window_handles[-1])
105
    driver.get('about:blank')
92 106
    driver.uninstall_addon(addon_id)
93 107
    ext_path.unlink()
94 108

  
test/unit/test_popup.py
235 235

  
236 236
@pytest.mark.ext_data(popup_ext_data)
237 237
@pytest.mark.usefixtures('webextension')
238
# Under Parabola's Iceweasel 75 the settings page's window opened during this
239
# test is impossible to close using driver.close() - it raises an exception with
240
# message 'closeTab() not supported in iceweasel'. To avoid such error during
241
# test cleanup, we use the mark below to tell our driver fixture to span a
242
# separate browser instance for this test.
243
@pytest.mark.second_driver()
238 244
def test_popup_settings_opening(driver, execute_in_page):
239 245
    """
240 246
    Test opening the settings page from popup through button click.

Also available in: Unified diff