Skip to content

Commit

Permalink
Merge pull request #5 from breadrock1/hotfix/check-urls-fault
Browse files Browse the repository at this point in the history
Hotfix: Check urls fault
  • Loading branch information
breadrock1 authored Jul 11, 2024
2 parents 839a459 + e3ffb3e commit 865e4c3
Show file tree
Hide file tree
Showing 16 changed files with 126,558 additions and 78 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
* Fix: Unpack and load native libraries @breadrock1 in https://github.com/breadrock1/Adblock-coffee/pull/3


**Full Changelog**: https://github.com/breadrock1/Adblock-coffee/compare/adblock-coffee-1.0.3...adblock-coffee-1.0.5
**Full Changelog**: https://github.com/breadrock1/Adblock-coffee/compare/adblock-coffee-1.0.3...adblock-coffee-1.0.6
17 changes: 14 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,24 @@ cargo build --release --manifest-path adblock-rs/Cargo.toml
mvn install
```

If you want to build library to another platform add option `--target` with needed platform like `aarch64-linux-android`, `armv7-linux-androideabi`, `i686-linux-android`.
To build it for android platforms just use ndk (see installation on official site):
```shell
cargo ndk -t aarch64-linux-android -o ./target build --release
mv arm64-v8 release
```

Go back to project root and enter:
```shell
mvn install
```

If you want to build library to another platform add option `--target` with needed platform like `aarch64-unknown-linux-gnu`, .
After that check that path of built library exists into `pom.xml` `maven-resources-plugin` section. As default `rustup` using current platform and creates `target/{debug,release}` directories.
After switching target platform by `rustup` these directories created as `targer/{target-platform}/{debug,release}` directories.

Example building library for `aarch64-linux-android` target:
Example building library for `aarch64-unknown-linux-gnu` target:
```shell
cargo build --release --target aarch64-linux-android --manifest-path adblock-rs/Cargo.toml
cargo build --release --target aarch64-unknown-linux-gnu --manifest-path adblock-rs/Cargo.toml
```

And you have to update `pom.xml` file:
Expand Down
10 changes: 8 additions & 2 deletions adblock-rs/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "adblock-coffee"
version = "0.1.3"
version = "0.1.4"
edition = "2021"
authors = ["Bread White <[email protected]>"]

Expand All @@ -10,6 +10,12 @@ crate_type = ["cdylib"]
[dependencies]
anyhow = "^1.0"
adblock = "^0.8"
env_logger = "0.11.3"
jni = "^0.21"
thiserror = "^1.0"
lazy_static = "1.5.0"
log = "0.4.22"
once_cell = "1.19.0"
thiserror = "^1.0"

[target.'cfg(target_os = "android")'.dependencies]
android_logger = "^0.14"
34 changes: 33 additions & 1 deletion adblock-rs/src/adblock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,15 @@ impl AdvtBlocker {
}
}

pub fn recreate(&mut self, filter_list: Vec<String>) {
let debug_info = true;
let mut filter_set = FilterSet::new(debug_info);
filter_set.add_filters(&filter_list, ParseOptions::default());

let filter_engine = Engine::from_filter_set(filter_set, true);
self.engine = filter_engine;
}

pub fn check_network_urls(
&self,
url: &str,
Expand All @@ -41,12 +50,15 @@ impl Default for AdvtBlocker {
}
}

unsafe impl Send for AdvtBlocker {}
unsafe impl Sync for AdvtBlocker {}

#[cfg(test)]
mod adblock_test {
use super::*;

#[test]
fn check_url() {
fn check_base_case() {
let rules = vec![
"-advertisement-icon.".to_string(),
"-advertisement-management/".to_string(),
Expand All @@ -65,4 +77,24 @@ mod adblock_test {

assert_eq!(check_result, true);
}

#[test]
fn check_failed_url() {
let rules = vec![
"-advertisement-icon.".to_string(),
"-advertisement-management/".to_string(),
"-advertisement.".to_string(),
"-advertisement/script.".to_string(),
];

let advt_blocker = AdvtBlocker::new(rules);
let check_result = advt_blocker
.check_network_urls("hvertisement-icon.", "http://exampworld", "kek")
.unwrap_or_else(|err| {
log::error!("{:?}", err.to_string());
false
});

assert_eq!(check_result, false);
}
}
19 changes: 18 additions & 1 deletion adblock-rs/src/errors.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use jni::errors::{Exception, ToException};
use jni::errors::{Error, Exception, ToException};

use adblock::request::RequestError;
use std::fmt::Debug;
use std::sync::PoisonError;
use thiserror::Error;

#[derive(Debug, Error)]
Expand All @@ -10,6 +11,10 @@ pub enum RustException {
CreateRequest(String),
#[error("Failed while extracting parameter: {0}")]
ExtractParameter(String),
#[error("Failed while lock mutex for AdvtBlocker: {0}")]
MutexGuardLock(String),
#[error("Jvm runtime error: {0}")]
JvmException(String),
}

impl ToException for RustException {
Expand All @@ -26,3 +31,15 @@ impl From<RequestError> for RustException {
RustException::CreateRequest(value.to_string())
}
}

impl<T> From<PoisonError<T>> for RustException {
fn from(value: PoisonError<T>) -> Self {
RustException::MutexGuardLock(value.to_string())
}
}

impl From<jni::errors::Error> for RustException {
fn from(value: Error) -> Self {
RustException::JvmException(value.to_string())
}
}
24 changes: 17 additions & 7 deletions adblock-rs/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
mod adblock;
mod errors;
mod logger;
mod wrapper;

use jni::objects::{JObject, JObjectArray, JString};
Expand All @@ -14,13 +15,22 @@ pub extern "system" fn Java_com_example_adblock_AdvtBlocker_initObject(
_class: JObject,
rules: JObjectArray,
) -> jlong {
match init_object_wrapped(&mut env, &rules) {
Ok(instance) => Box::into_raw(Box::new(instance)) as jlong,
Err(err) => {
log::error!("{:?}", err);
0_i64 as jlong
}
}
init_object_wrapped(&mut env, &rules).unwrap_or_else(|err| {
log::error!("{:?}", err);
-1_i64 as jlong
})
}

#[no_mangle]
pub extern "system" fn Java_com_example_adblock_AdvtBlocker_destroyObject(
mut env: JNIEnv,
_class: JObject,
ptr: jlong,
) -> jboolean {
destroy_object_wrapped(&mut env, ptr).unwrap_or_else(|err| {
log::error!("{:?}", err);
false as jboolean
})
}

#[no_mangle]
Expand Down
32 changes: 32 additions & 0 deletions adblock-rs/src/logger.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
use lazy_static::lazy_static;
use std::sync::Once;

#[cfg(target_os = "android")]
use {android_logger::Config, log::LevelFilter};

#[cfg(not(target_os = "android"))]
use {env_logger::Builder, log::LevelFilter};

lazy_static! {
static ref _LOGGER: Once = {
let init = Once::new();

#[cfg(target_os = "android")]
init.call_once(|| {
android_logger::init_once(
Config::default()
.with_tag("Tag_RustAdvtBlocker")
.with_max_level(LevelFilter::max()),
);
});

#[cfg(not(target_os = "android"))]
init.call_once(|| {
let mut builder = Builder::new();
builder.filter_level(LevelFilter::Debug);
builder.init();
});

init
};
}
87 changes: 55 additions & 32 deletions adblock-rs/src/wrapper.rs
Original file line number Diff line number Diff line change
@@ -1,48 +1,67 @@
use jni::objects::{JObjectArray, JString};
use jni::sys::{jboolean, jlong};
use jni::JNIEnv;
use lazy_static::lazy_static;
use once_cell::sync::Lazy;
use std::sync::Mutex;

use crate::adblock::AdvtBlocker;
use crate::errors::RustException;

lazy_static! {
static ref INSTANCE: Lazy<Mutex<AdvtBlocker>> = Lazy::new(|| {
let init: Mutex<AdvtBlocker> = Mutex::new(AdvtBlocker::default());
init
});
}

pub(crate) fn init_object_wrapped(
env: &mut JNIEnv,
rules: &JObjectArray,
) -> Result<AdvtBlocker, RustException> {
) -> Result<jlong, RustException> {
let conv_rules = extract_list_str(env, rules)?;
Ok(AdvtBlocker::new(conv_rules))
let mut instance_lock = INSTANCE.lock().map_err(RustException::from)?;

instance_lock.recreate(conv_rules);

let ptr = Box::into_raw(Box::new(&INSTANCE));
Ok(ptr as jlong)
}

pub(crate) fn destroy_object_wrapped(
_env: &mut JNIEnv,
_ptr: jlong,
) -> Result<jboolean, RustException> {
let instance_lock = INSTANCE.lock().map_err(RustException::from)?;

drop(instance_lock);
Ok(true as jboolean)
}

pub(crate) fn check_net_urls_wrapped(
env: &mut JNIEnv,
ptr: jlong,
_ptr: jlong,
url: &JString,
src_url: &JString,
req_type: &JString,
) -> Result<jboolean, RustException> {
unsafe {
let advt_blocker = &mut *(ptr as *mut AdvtBlocker);
let advt_blocker = INSTANCE.lock().map_err(RustException::from)?;

let url_str = extract_str(env, url)?;
let url_str = extract_str(env, url)?;
let src_url_str = extract_str(env, src_url)?;
let req_type_str = extract_str(env, req_type)?;

let src_url_str = extract_str(env, src_url)?;
let check_result = advt_blocker.check_network_urls(
url_str.as_str(),
src_url_str.as_str(),
req_type_str.as_str(),
)?;

let req_type_str = extract_str(env, req_type)?;

let check_result = advt_blocker.check_network_urls(
url_str.as_str(),
src_url_str.as_str(),
req_type_str.as_str(),
)?;

Ok(check_result as jboolean)
}
Ok(check_result as jboolean)
}

fn extract_str<'a>(env: &'a mut JNIEnv, j_obj: &'a JString) -> Result<String, RustException> {
let j_str = env
.get_string(&j_obj)
.map_err(|err| RustException::ExtractParameter(err.to_string()))?;
let j_str = env.get_string(&j_obj).map_err(RustException::from)?;

let str_obj = j_str
.to_str()
Expand All @@ -55,22 +74,26 @@ fn extract_list_str<'a>(
env: &'a mut JNIEnv,
j_obj_arr: &'a JObjectArray,
) -> Result<Vec<String>, RustException> {
let j_list = env
.get_list(&j_obj_arr)
.map_err(|err| RustException::ExtractParameter(err.to_string()))?;
let j_list = env.get_list(&j_obj_arr).map_err(RustException::from)?;

let j_list_size = j_list
.size(env)
.map_err(|err| RustException::ExtractParameter(err.to_string()))?;
let j_list_size = j_list.size(env).map_err(RustException::from)?;

let mut list_data = Vec::with_capacity(j_list_size as usize);
for index in 0..j_list_size {
let j_obj = j_list
.get(env, index)
.map_err(|err| RustException::ExtractParameter(err.to_string()))?
.unwrap();

let j_str = JString::from(j_obj);
let j_obj_get_result = j_list.get(env, index);
if j_obj_get_result.is_err() {
let err = j_obj_get_result.err().unwrap();
log::warn!("failed to parse rules: {:?}", err);
continue;
}

let j_obj_opt = j_obj_get_result?;
if j_obj_opt.is_none() {
log::warn!("parsed rule is none. skipped...");
continue;
}

let j_str = JString::from(j_obj_opt.unwrap());
let str_data = extract_str(env, &j_str)?;
list_data.push(str_data);
}
Expand Down
4 changes: 2 additions & 2 deletions examples/simple/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
<version>1.0.5</version>
<type>jar</type>
<overWrite>false</overWrite>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
<outputDirectory>${project.build.outputDirectory}/lib</outputDirectory>
</artifactItem>
</artifactItems>
</configuration>
Expand All @@ -75,7 +75,7 @@
<artifactId>maven-surefire-plugin</artifactId>
<version>2.17</version>
<configuration>
<argLine>-Djava.library.path=${project.build.directory}/lib</argLine>
<argLine>-Djava.library.path=${project.build.outputDirectory}/lib/lib</argLine>
</configuration>
</plugin>
<plugin>
Expand Down
Loading

0 comments on commit 865e4c3

Please sign in to comment.