Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ harness = false
default = ["embedded-domain-resolver", "full-regex-handling", "single-thread"]
full-regex-handling = []
single-thread = [] # disables `Send` and `Sync` on `Engine`.
regex-debug-info = []
debug-info = []
css-validation = ["cssparser", "selectors"]
content-blocking = []
embedded-domain-resolver = ["addr"] # Requires setting an external domain resolver if disabled.
Expand Down
15 changes: 0 additions & 15 deletions js/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -323,20 +323,6 @@ fn engine_clear_tags(mut cx: FunctionContext) -> JsResult<JsNull> {
Ok(JsNull::new(&mut cx))
}

fn engine_add_resource(mut cx: FunctionContext) -> JsResult<JsBoolean> {
let this = cx.argument::<JsBox<Engine>>(0)?;

let resource_arg = cx.argument::<JsValue>(1)?;
let resource: Resource = json_ffi::from_js(&mut cx, resource_arg)?;

let success = if let Ok(mut engine) = this.0.lock() {
engine.add_resource(resource).is_ok()
} else {
cx.throw_error("Failed to acquire lock on engine")?
};
Ok(cx.boolean(success))
}

fn validate_request(mut cx: FunctionContext) -> JsResult<JsBoolean> {
let url: String = cx.argument::<JsString>(0)?.value(&mut cx);
let source_url: String = cx.argument::<JsString>(1)?.value(&mut cx);
Expand Down Expand Up @@ -424,7 +410,6 @@ register_module!(mut m, {
m.export_function("Engine_useResources", engine_use_resources)?;
m.export_function("Engine_tagExists", engine_tag_exists)?;
m.export_function("Engine_clearTags", engine_clear_tags)?;
m.export_function("Engine_addResource", engine_add_resource)?;

m.export_function("validateRequest", validate_request)?;
m.export_function("uBlockResources", ublock_resources)?;
Expand Down
4 changes: 2 additions & 2 deletions src/blocker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -487,13 +487,13 @@ impl Blocker {
regex_manager.set_discard_policy(new_discard_policy);
}

#[cfg(feature = "regex-debug-info")]
#[cfg(feature = "debug-info")]
pub fn discard_regex(&self, regex_id: u64) {
let mut regex_manager = self.borrow_regex_manager();
regex_manager.discard_regex(regex_id);
}

#[cfg(feature = "regex-debug-info")]
#[cfg(feature = "debug-info")]
pub fn get_regex_debug_info(&self) -> crate::regex_manager::RegexDebugInfo {
let regex_manager = self.borrow_regex_manager();
regex_manager.get_debug_info()
Expand Down
52 changes: 40 additions & 12 deletions src/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use crate::flatbuffers::unsafe_tools::VerifiedFlatbufferMemory;
use crate::lists::{FilterSet, ParseOptions};
use crate::regex_manager::RegexManagerDiscardPolicy;
use crate::request::Request;
use crate::resources::{Resource, ResourceStorage};
use crate::resources::{Resource, ResourceStorage, ResourceStorageBackend};

use std::collections::HashSet;

Expand Down Expand Up @@ -58,6 +58,12 @@ pub struct Engine {
filter_data_context: FilterDataContextRef,
}

#[cfg(feature = "debug-info")]
pub struct EngineDebugInfo {
pub regex_debug_info: crate::regex_manager::RegexDebugInfo,
pub flatbuffer_size: usize,
}

impl Default for Engine {
fn default() -> Self {
Self::from_filter_set(FilterSet::new(false), false)
Expand Down Expand Up @@ -187,17 +193,36 @@ impl Engine {
self.blocker.tags_enabled().contains(&tag.to_owned())
}

/// Sets this engine's resources to be _only_ the ones provided in `resources`.
/// Sets this engine's [Resource]s to be _only_ the ones provided in `resources`.
///
/// The resources will be held in-memory. If you have special caching, management, or sharing
/// requirements, consider [Engine::use_resource_storage] instead.
pub fn use_resources(&mut self, resources: impl IntoIterator<Item = Resource>) {
self.resources = ResourceStorage::from_resources(resources);
let storage = crate::resources::InMemoryResourceStorage::from_resources(resources);
self.use_resource_storage(storage);
}

/// Sets this engine's resources to additionally include `resource`.
pub fn add_resource(
/// Sets this engine's backend for [Resource] storage to a custom implementation of
/// [ResourceStorageBackend].
///
/// If you're okay with the [Engine] holding these resources in-memory, use
/// [Engine::use_resources] instead.
#[cfg(not(feature = "single-thread"))]
pub fn use_resource_storage<R: ResourceStorageBackend + 'static + Sync + Send>(
&mut self,
resource: Resource,
) -> Result<(), crate::resources::AddResourceError> {
self.resources.add_resource(resource)
resources: R,
) {
self.resources = ResourceStorage::from_backend(resources);
}

/// Sets this engine's backend for [Resource] storage to a custom implementation of
/// [ResourceStorageBackend].
///
/// If you're okay with the [Engine] holding these resources in-memory, use
/// [Engine::use_resources] instead.
#[cfg(feature = "single-thread")]
pub fn use_resource_storage<R: ResourceStorageBackend + 'static>(&mut self, resources: R) {
self.resources = ResourceStorage::from_backend(resources);
}

// Cosmetic filter functionality
Expand Down Expand Up @@ -241,14 +266,17 @@ impl Engine {
self.blocker.set_regex_discard_policy(new_discard_policy);
}

#[cfg(feature = "regex-debug-info")]
#[cfg(feature = "debug-info")]
pub fn discard_regex(&mut self, regex_id: u64) {
self.blocker.discard_regex(regex_id);
}

#[cfg(feature = "regex-debug-info")]
pub fn get_regex_debug_info(&self) -> crate::regex_manager::RegexDebugInfo {
self.blocker.get_regex_debug_info()
#[cfg(feature = "debug-info")]
pub fn get_debug_info(&self) -> EngineDebugInfo {
EngineDebugInfo {
regex_debug_info: self.blocker.get_regex_debug_info(),
flatbuffer_size: self.filter_data_context.memory.data().len(),
}
}

/// Serializes the `Engine` into a binary format so that it can be quickly reloaded later.
Expand Down
12 changes: 6 additions & 6 deletions src/regex_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ const DEFAULT_DISCARD_UNUSED_TIME: Duration = Duration::from_secs(180);

/// Reports [`RegexManager`] metrics that may be useful for creating an optimized
/// [`RegexManagerDiscardPolicy`].
#[cfg(feature = "regex-debug-info")]
#[cfg(feature = "debug-info")]
pub struct RegexDebugInfo {
/// Information about each regex contained in the [`RegexManager`].
pub regex_data: Vec<RegexDebugEntry>,
Expand All @@ -48,7 +48,7 @@ pub struct RegexDebugInfo {
}

/// Describes metrics about a single regex from the [`RegexManager`].
#[cfg(feature = "regex-debug-info")]
#[cfg(feature = "debug-info")]
pub struct RegexDebugEntry {
/// Id for this particular regex, which is constant and unique for its lifetime.
///
Expand Down Expand Up @@ -312,7 +312,7 @@ impl RegexManager {
}

/// Discard one regex, identified by its id from a [`RegexDebugEntry`].
#[cfg(feature = "regex-debug-info")]
#[cfg(feature = "debug-info")]
pub fn discard_regex(&mut self, regex_id: u64) {
self.map
.iter_mut()
Expand All @@ -322,7 +322,7 @@ impl RegexManager {
});
}

#[cfg(feature = "regex-debug-info")]
#[cfg(feature = "debug-info")]
pub(crate) fn get_debug_regex_data(&self) -> Vec<RegexDebugEntry> {
use itertools::Itertools;
self.map
Expand All @@ -336,13 +336,13 @@ impl RegexManager {
.collect_vec()
}

#[cfg(feature = "regex-debug-info")]
#[cfg(feature = "debug-info")]
pub(crate) fn get_compiled_regex_count(&self) -> usize {
self.compiled_regex_count
}

/// Collect metrics that may be useful for creating an optimized [`RegexManagerDiscardPolicy`].
#[cfg(feature = "regex-debug-info")]
#[cfg(feature = "debug-info")]
pub fn get_debug_info(&self) -> RegexDebugInfo {
RegexDebugInfo {
regex_data: self.get_debug_regex_data(),
Expand Down
11 changes: 7 additions & 4 deletions src/resources/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@ pub mod resource_assembler;
mod resource_storage;
pub(crate) use resource_storage::parse_scriptlet_args;
#[doc(inline)]
pub use resource_storage::{AddResourceError, ResourceStorage, ScriptletResourceError};
pub use resource_storage::{
AddResourceError, InMemoryResourceStorage, ResourceStorage, ResourceStorageBackend,
ScriptletResourceError,
};

use memchr::memrchr as find_char_reverse;
use serde::{Deserialize, Serialize};
Expand All @@ -34,7 +37,7 @@ use serde::{Deserialize, Serialize};
/// ```
/// # use adblock::Engine;
/// # use adblock::lists::ParseOptions;
/// # use adblock::resources::{MimeType, PermissionMask, Resource, ResourceType};
/// # use adblock::resources::{MimeType, PermissionMask, Resource, ResourceStorage, ResourceType};
/// # let mut filter_set = adblock::lists::FilterSet::default();
/// # let untrusted_filters = vec![""];
/// # let trusted_filters = vec![""];
Expand All @@ -59,14 +62,14 @@ use serde::{Deserialize, Serialize};
/// let mut engine = Engine::from_filter_set(filter_set, true);
/// // The `trusted-set-cookie` scriptlet cannot be injected without `COOKIE_ACCESS`
/// // permission.
/// engine.add_resource(Resource {
/// engine.use_resources([Resource {
/// name: "trusted-set-cookie.js".to_string(),
/// aliases: vec![],
/// kind: ResourceType::Mime(MimeType::ApplicationJavascript),
/// content: base64::encode("document.cookie = '...';"),
/// dependencies: vec![],
/// permission: COOKIE_ACCESS,
/// });
/// }]);
/// ```
#[derive(Serialize, Deserialize, Clone, Copy, Default)]
#[repr(transparent)]
Expand Down
Loading
Loading