diff options
author | Mark H Weaver <mhw@netris.org> | 2023-09-27 00:53:30 -0400 |
---|---|---|
committer | Mark H Weaver <mhw@netris.org> | 2023-09-27 14:34:35 -0400 |
commit | fa5c0b073214191e6996ba0b5bc8e61560ff822c (patch) | |
tree | 38e7133195616f4a4da6c8fe46ab2c77c5a6e9e2 /data/extensions/jsr@javascriptrestrictor/fp_code_builders.js | |
parent | d167f676a167b1392a4e29f14ddf25613468680b (diff) |
Update the JShelter extension to 0.15.2.
Diffstat (limited to 'data/extensions/jsr@javascriptrestrictor/fp_code_builders.js')
-rw-r--r-- | data/extensions/jsr@javascriptrestrictor/fp_code_builders.js | 204 |
1 files changed, 79 insertions, 125 deletions
diff --git a/data/extensions/jsr@javascriptrestrictor/fp_code_builders.js b/data/extensions/jsr@javascriptrestrictor/fp_code_builders.js index 4378a84..02467fa 100644 --- a/data/extensions/jsr@javascriptrestrictor/fp_code_builders.js +++ b/data/extensions/jsr@javascriptrestrictor/fp_code_builders.js @@ -2,6 +2,7 @@ * \brief Functions that help to automate process of building wrapping code for FPD module * * \author Copyright (C) 2021 Marek Salon + * \author Copyright (C) 2023 Martin Zmitko * * \license SPDX-License-Identifier: GPL-3.0-or-later */ @@ -19,28 +20,6 @@ // along with this program. If not, see <https://www.gnu.org/licenses/>. // -/** \file - * - * \brief This file is part of Fingerprint Detector (FPD) and contains helper functions for automated wrappers creation. - * File also contains loading routine for FPD configuration files (groups-lvl_X.json, wrappers-lvl_X.json, etc...). - * - * \ingroup FPD - */ - -//DEF_FPD_FILES_S -var fp_config_files = ["groups-lvl_0", "groups-lvl_1", "wrappers-lvl_0_1"] -//DEF_FPD_FILES_E - -/** - * The object carrying code for builded FPD wrappers - */ -var fp_wrapped_codes = {}; - -/** - * Object containing parsed input from JSON configuration files of FPD module. - */ -var fp_levels = {}; - /** * Additional wrappers for specialized purposes. */ @@ -113,92 +92,46 @@ var additional_wrappers = [ } ] -/// \cond (Exclude this section from the doxygen documentation. If this section is not excluded, it is documented as a separate function.) -{ - // parse input files into fp_levels for each level, generate wrapping code and initialize FPD module - let loadFpdConfig = async () => { - for (let file of fp_config_files) { - try { - let config = JSON.parse(await readFile(browser.runtime.getURL(`fp_config/${file}.json`))); - let file_splitted = file.split("-"); - let file_levels = file_splitted[1].split("_").filter(x => x != 'lvl'); - fp_levels[file_splitted[0]] = fp_levels[file_splitted[0]] || {}; - for (let level of file_levels) { - fp_levels[file_splitted[0]][level] = config; - } - } - catch (e) { - console.error(e); - } +/** + * The function that generates wrapping code from FPD wrappers when JSS hasn't wrapped anything. + * + * \param fpd_wrappers Array of wrappers defined by FPD configuration. + * + * \returns Injectable code created from FPD wrappers. + */ +function fp_generate_from_wrappers(fpd_wrappers) { + // define wrapper for each FPD endpoint (using default JSS definition of wrappers) + let tmp_build_wrapping_code = {}; + for (let wrap_item of fpd_wrappers) { + if (wrap_item[1]) { // wrap_item.type === "property" + tmp_build_wrapping_code[wrap_item[0]] = fp_build_property_wrapper(wrap_item); } - - // merge duplicit entries of the same resource to be wrapped only once - let mergeWrappers = (sameResources) => { - let mergeGroups = () => { - let accArray = []; - for (let resource of sameResources) { - accArray.push(...resource.groups); - } - return accArray; - } - - return { - resource: sameResources[0].resource, - type: sameResources[0].type, - groups: mergeGroups() - } + else { // wrap_item.type === "function" + tmp_build_wrapping_code[wrap_item[0]] = fp_build_function_wrapper(wrap_item); } + } - for (let level in fp_levels.wrappers) { - let tmpWrappers = {}; - for (let wrapper of fp_levels.wrappers[level]) { - if (!Object.keys(tmpWrappers).includes(wrapper.resource)) { - let sameResources = fp_levels.wrappers[level].filter(x => x.resource == wrapper.resource); - tmpWrappers[wrapper.resource] = mergeWrappers(sameResources); - } - } - fp_levels.wrappers[level] = Object.values(tmpWrappers); + // if there is an additional wrapper for resource, overwrite default definition with it + for (let additional_item of additional_wrappers) { + let { parent_object, parent_object_property } = additional_item; + let resource = `${parent_object}.${parent_object_property}`; + if (resource in tmp_build_wrapping_code) { + tmp_build_wrapping_code[resource] = additional_item; } + } - for (let level in fp_levels.wrappers) { - // define wrapper for each FPD endpoint (using default JSS definition of wrappers) - let tmp_build_wrapping_code = {}; - for (let wrap_item of fp_levels.wrappers[level]) { - if (wrap_item.type == "property") { - tmp_build_wrapping_code[wrap_item.resource] = fp_build_property_wrapper(wrap_item); - } - else if (wrap_item.type == "function") { - tmp_build_wrapping_code[wrap_item.resource] = fp_build_function_wrapper(wrap_item); - } - } - - // if there is an additional wrapper for resource, overwrite default definition with it - for (let additional_item of additional_wrappers) { - let { parent_object, parent_object_property } = additional_item; - let resource = `${parent_object}.${parent_object_property}`; - if (resource in tmp_build_wrapping_code) { - tmp_build_wrapping_code[resource] = additional_item; - } - } - - // transform each wrapper to wrapping code and index it in memory for quick access - fp_wrapped_codes[level] = {}; - for (let build_item in tmp_build_wrapping_code) { - try { - fp_wrapped_codes[level][build_item] = build_code(tmp_build_wrapping_code[build_item]); - } catch (e) { - console.error(e); - fp_wrapped_codes[level][build_item] = ""; - } - } + // transform each wrapper to wrapping code + let fp_wrapped_codes = {}; + for (let build_item in tmp_build_wrapping_code) { + try { + fp_wrapped_codes[build_item] = build_code(tmp_build_wrapping_code[build_item]); + } catch (e) { + console.error(e); + fp_wrapped_codes[build_item] = ""; } - - // initialize FPD module (background script and event listeners) - initFpd(); } - loadFpdConfig(); + return fp_wrapped_codes; } -/// \endcond /** * The function that appends FPD wrappers into injectable code, if JSS hasn't wrapped certain FPD endpoints already. @@ -209,26 +142,24 @@ var additional_wrappers = [ * * \returns Modified injectable code that also contains FPD wrapping code. */ -function fp_update_wrapping_code(code, jss_wrappers, fpd_level) { - let fpd_wrappers = Object.keys(fp_wrapped_codes[fpd_level]) - .filter(key => !jss_wrappers.map(x => x[0]).includes(key)) - .reduce((obj, key) => { - obj[key] = fp_wrapped_codes[fpd_level][key]; - return obj; - }, {}); - let fpd_code = joinWrappingCode(Object.values(fpd_wrappers)); +function fp_update_wrapping_code(code, jss_wrappers, fpd_wrappers) { + const jss_wrapper_resources = jss_wrappers.map(x => x[0]); + const fpd_wrappers_filtered = fpd_wrappers.filter(w => !jss_wrapper_resources.includes(w[0])); + const fpd_wrapped_codes = fp_generate_from_wrappers(fpd_wrappers_filtered); + const fpd_code = joinWrappingCode(Object.values(fpd_wrapped_codes)); return code.replace("// FPD_S\n", `// FPD_S\n ${fpd_code}`); } /** * The function that creates injectable code specifically for FPD wrappers in case that JSS hasn't wrapped anything. * - * \param fpd_level Identifier of the current FPD level/config. + * \param fpd_wrappers Array of wrappers defined by FPD configuration. * * \returns Injectable code containing only FPD wrapping code. */ -function fp_generate_wrapping_code(fpd_level) { - return generate_code("// FPD_S\n" + joinWrappingCode(Object.values(fp_wrapped_codes[fpd_level])) + "\n// FPD_E"); +function fp_generate_wrapping_code(fpd_wrappers) { + let fpd_wrapped_codes = fp_generate_from_wrappers(fpd_wrappers); + return generate_code("// FPD_S\n" + joinWrappingCode(Object.values(fpd_wrapped_codes)) + "\n// FPD_E"); } /** @@ -240,10 +171,10 @@ function fp_generate_wrapping_code(fpd_level) { * \returns Object consisting of two properties (path, name) for given resource. */ function split_resource(text) { - var index = text.lastIndexOf('.'); - return { + var index = text.lastIndexOf('.'); + return { path: text.slice(0, index), - name: text.slice(index + 1) + name: text.slice(index + 1) } } @@ -257,14 +188,10 @@ function split_resource(text) { function fp_build_property_wrapper(wrap_item) { // return object initialization var wrapper_object = {}; - - // get unique array of property types (set, get), if property not defined => implicit get - var propTypes = Array.from(new Set(wrap_item.groups.map( - (x) => { return x.property != undefined ? x.property : "get" }))); // if properties to wrap exist, create property wrapper based on wrap_item input - if (propTypes.size != 0) { - var resource_splitted = split_resource(wrap_item.resource); + if (wrap_item[2].size != 0) { + var resource_splitted = split_resource(wrap_item[0]); wrapper_object = { parent_object: resource_splitted["path"], parent_object_property: resource_splitted["name"], @@ -276,19 +203,20 @@ function fp_build_property_wrapper(wrap_item) { parent_object_property: resource_splitted["name"], wrapped_objects: [], wrapped_properties: [], + report_args: wrap_item[3], } ], }; // create post_wrapping_code to wrap every property type - for (let type of propTypes) { + for (let type of wrap_item[2]) { // save original resource - get property from descriptor, if do not exists, save it directly wrapper_object.post_wrapping_code[0].wrapped_objects.push({ original_name: ` Object.getOwnPropertyDescriptor(${resource_splitted["path"]}, "${resource_splitted["name"]}") ? Object.getOwnPropertyDescriptor(${resource_splitted["path"]}, "${resource_splitted["name"]}")["${type}"] : - ${type == "get" ? wrap_item.resource : undefined} + ${type == "get" ? wrap_item[0] : undefined} `, wrapped_name: `originalD_${type}`, }); @@ -313,8 +241,8 @@ function fp_build_property_wrapper(wrap_item) { * \returns New declarative function wrapper supported by code_builder (same structure as explicitly defined wrappers). */ function fp_build_function_wrapper(wrap_item) { - var resource_splitted = split_resource(wrap_item.resource); - + var resource_splitted = split_resource(wrap_item[0]); + var wrapper_object = { parent_object: resource_splitted["path"], parent_object_property: resource_splitted["name"], @@ -325,11 +253,37 @@ function fp_build_function_wrapper(wrap_item) { wrapped_name: `originalF_${resource_splitted["name"]}` }], wrapping_function_args: "...args", - + // call original function on return with same arguments and context (do not change semantics) wrapping_function_body: ` return originalF_${resource_splitted["name"]}.call(this, ...args); `, + report_args: wrap_item[3], }; return wrapper_object; } + +/** + * The function that adds argument reporting settings to every JSS wrapper definition where specified by FPD configuration. + * This is for removing unnecessary reporting of arguments in cases where the arguments may be large + * (such as arrays for image/audio data), which results in their slow synchronous serialization. + * + * \param fpd_wrappers Array of wrappers defined by FPD configuration. + */ +function fp_append_reporting_to_jss_wrappers(fpd_wrappers) { + const resources_with_reporting = new Set(fpd_wrappers.map(w => w[3] ? w[0] : undefined)); + resources_with_reporting.delete(undefined); + function append_reporting(wrapper) { + let {parent_object, parent_object_property} = wrapper; + let resource = `${parent_object}.${parent_object_property}`; + wrapper.report_args = resources_with_reporting.has(resource); + } + + for (let wrapper of Object.values(build_wrapping_code)) { + append_reporting(wrapper); + if (wrapper.post_wrapping_code) { + // Objects wrapped in post wrapping code might be tracked as well + Object.values(wrapper.post_wrapping_code).forEach(append_reporting); + } + } +} |