mirror of
https://github.com/starovoid/rxing.git
synced 2026-07-27 21:02:35 +00:00
move all regex into lazy static
This commit is contained in:
@@ -2,13 +2,16 @@ use regex::Regex;
|
|||||||
|
|
||||||
use crate::common::BitArray;
|
use crate::common::BitArray;
|
||||||
|
|
||||||
const SPACES :&str= "\\s+";
|
use lazy_static::lazy_static;
|
||||||
const DOTX : &str = "[^.X]";
|
|
||||||
|
lazy_static! {
|
||||||
|
static ref SPACES: Regex =Regex::new("\\s+").unwrap();
|
||||||
|
static ref DOTX: Regex = Regex::new("[^.X]").unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
pub fn toBitArray( bits:&str) -> BitArray{
|
pub fn toBitArray( bits:&str) -> BitArray{
|
||||||
let mut ba_in = BitArray::new();
|
let mut ba_in = BitArray::new();
|
||||||
let replacer_regex = Regex::new(DOTX).unwrap();
|
let str = DOTX.replace_all(bits, "");
|
||||||
let str = replacer_regex.replace_all(bits, "");
|
|
||||||
for a_str in str.chars() {
|
for a_str in str.chars() {
|
||||||
// for (char aStr : str) {
|
// for (char aStr : str) {
|
||||||
ba_in.appendBit(a_str == 'X');
|
ba_in.appendBit(a_str == 'X');
|
||||||
@@ -27,6 +30,5 @@ pub fn toBitArray( bits:&str) -> BitArray{
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn stripSpace( s:&str) -> String{
|
pub fn stripSpace( s:&str) -> String{
|
||||||
let replacer_regex = Regex::new(SPACES).unwrap();
|
SPACES.replace_all(s, "").to_string()
|
||||||
replacer_regex.replace_all(s, "").to_string()
|
|
||||||
}
|
}
|
||||||
@@ -30,6 +30,7 @@
|
|||||||
use chrono::{Date, DateTime, Local, NaiveDateTime, TimeZone, Utc};
|
use chrono::{Date, DateTime, Local, NaiveDateTime, TimeZone, Utc};
|
||||||
use chrono_tz::Tz;
|
use chrono_tz::Tz;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
|
use lazy_static::lazy_static;
|
||||||
|
|
||||||
use crate::exceptions::Exceptions;
|
use crate::exceptions::Exceptions;
|
||||||
|
|
||||||
@@ -38,8 +39,8 @@ use super::{
|
|||||||
ResultParser,
|
ResultParser,
|
||||||
};
|
};
|
||||||
|
|
||||||
const RFC2445_DURATION: &'static str =
|
// const RFC2445_DURATION: &'static str =
|
||||||
"P(?:(\\d+)W)?(?:(\\d+)D)?(?:T(?:(\\d+)H)?(?:(\\d+)M)?(?:(\\d+)S)?)?";
|
// "P(?:(\\d+)W)?(?:(\\d+)D)?(?:T(?:(\\d+)H)?(?:(\\d+)M)?(?:(\\d+)S)?)?";
|
||||||
const RFC2445_DURATION_FIELD_UNITS: [i64; 5] = [
|
const RFC2445_DURATION_FIELD_UNITS: [i64; 5] = [
|
||||||
7 * 24 * 60 * 60 * 1000i64, // 1 week
|
7 * 24 * 60 * 60 * 1000i64, // 1 week
|
||||||
24 * 60 * 60 * 1000i64, // 1 day
|
24 * 60 * 60 * 1000i64, // 1 day
|
||||||
@@ -48,7 +49,11 @@ const RFC2445_DURATION_FIELD_UNITS: [i64; 5] = [
|
|||||||
1000i64, // 1 second
|
1000i64, // 1 second
|
||||||
];
|
];
|
||||||
|
|
||||||
const DATE_TIME: &'static str = "[0-9]{8}(T[0-9]{6}Z?)?";
|
lazy_static! {
|
||||||
|
static ref DATE_TIME : Regex = Regex::new("[0-9]{8}(T[0-9]{6}Z?)?").unwrap();
|
||||||
|
static ref RFC2445_DURATION: Regex = Regex::new("P(?:(\\d+)W)?(?:(\\d+)D)?(?:T(?:(\\d+)H)?(?:(\\d+)M)?(?:(\\d+)S)?)?").unwrap();
|
||||||
|
}
|
||||||
|
// const DATE_TIME: &'static str = "[0-9]{8}(T[0-9]{6}Z?)?";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a parsed result that encodes a calendar event at a certain time, optionally
|
* Represents a parsed result that encodes a calendar event at a certain time, optionally
|
||||||
@@ -162,8 +167,8 @@ impl CalendarParsedRXingResult {
|
|||||||
* @throws ParseException if not able to parse as a date
|
* @throws ParseException if not able to parse as a date
|
||||||
*/
|
*/
|
||||||
fn parseDate(when: String) -> Result<i64, Exceptions> {
|
fn parseDate(when: String) -> Result<i64, Exceptions> {
|
||||||
let date_time_regex = Regex::new(DATE_TIME).unwrap();
|
// let date_time_regex = Regex::new(DATE_TIME).unwrap();
|
||||||
if !date_time_regex.is_match(&when) {
|
if !DATE_TIME.is_match(&when) {
|
||||||
return Err(Exceptions::ParseException(when));
|
return Err(Exceptions::ParseException(when));
|
||||||
}
|
}
|
||||||
if when.len() == 8 {
|
if when.len() == 8 {
|
||||||
@@ -261,8 +266,8 @@ impl CalendarParsedRXingResult {
|
|||||||
if durationString.is_empty() {
|
if durationString.is_empty() {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
let regex = Regex::new(RFC2445_DURATION).unwrap();
|
// let regex = Regex::new(RFC2445_DURATION).unwrap();
|
||||||
if let Some(m) = regex.captures(durationString) {
|
if let Some(m) = RFC2445_DURATION.captures(durationString) {
|
||||||
let mut durationMS = 0i64;
|
let mut durationMS = 0i64;
|
||||||
for i in 0..RFC2445_DURATION_FIELD_UNITS.len() {
|
for i in 0..RFC2445_DURATION_FIELD_UNITS.len() {
|
||||||
// for (int i = 0; i < RFC2445_DURATION_FIELD_UNITS.length; i++) {
|
// for (int i = 0; i < RFC2445_DURATION_FIELD_UNITS.length; i++) {
|
||||||
|
|||||||
@@ -24,6 +24,12 @@
|
|||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
|
|
||||||
use crate::RXingResult;
|
use crate::RXingResult;
|
||||||
|
use lazy_static::lazy_static;
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
static ref COMMA :Regex = Regex::new(",").unwrap();
|
||||||
|
static ref ATEXT_ALPHANUMERIC:Regex = Regex::new("[a-zA-Z0-9@.!#$%&'*+\\-/=?^_`{|}~]+").unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
use super::{ParsedClientResult, ResultParser, EmailDoCoMoResultParser, EmailAddressParsedRXingResult};
|
use super::{ParsedClientResult, ResultParser, EmailDoCoMoResultParser, EmailAddressParsedRXingResult};
|
||||||
|
|
||||||
@@ -34,7 +40,7 @@ use super::{ParsedClientResult, ResultParser, EmailDoCoMoResultParser, EmailAddr
|
|||||||
* @author Sean Owen
|
* @author Sean Owen
|
||||||
*/
|
*/
|
||||||
pub fn parse(result: &RXingResult) -> Option<ParsedClientResult> {
|
pub fn parse(result: &RXingResult) -> Option<ParsedClientResult> {
|
||||||
let comma_regex = Regex::new(",").unwrap();
|
// let comma_regex = Regex::new(",").unwrap();
|
||||||
// private static final Pattern COMMA = Pattern.compile(",");
|
// private static final Pattern COMMA = Pattern.compile(",");
|
||||||
let rawText = ResultParser::getMassagedText(result);
|
let rawText = ResultParser::getMassagedText(result);
|
||||||
if rawText.starts_with("mailto:") || rawText.starts_with("MAILTO:") {
|
if rawText.starts_with("mailto:") || rawText.starts_with("MAILTO:") {
|
||||||
@@ -60,7 +66,7 @@ use super::{ParsedClientResult, ResultParser, EmailDoCoMoResultParser, EmailAddr
|
|||||||
let mut tos = if hostEmail.is_empty() {
|
let mut tos = if hostEmail.is_empty() {
|
||||||
Vec::new()
|
Vec::new()
|
||||||
}else {
|
}else {
|
||||||
comma_regex.split(hostEmail).into_iter().map(|s| s.to_owned()).collect()
|
COMMA.split(hostEmail).into_iter().map(|s| s.to_owned()).collect()
|
||||||
};
|
};
|
||||||
// if (!hostEmail.isEmpty()) {
|
// if (!hostEmail.isEmpty()) {
|
||||||
// tos = COMMA.split(hostEmail);
|
// tos = COMMA.split(hostEmail);
|
||||||
@@ -74,20 +80,20 @@ use super::{ParsedClientResult, ResultParser, EmailDoCoMoResultParser, EmailAddr
|
|||||||
// if (nameValues != null) {
|
// if (nameValues != null) {
|
||||||
if tos.is_empty() {
|
if tos.is_empty() {
|
||||||
if let Some(tosString) = nv.get("to"){
|
if let Some(tosString) = nv.get("to"){
|
||||||
tos = comma_regex.split(tosString).into_iter().map(|s| s.to_owned()).collect();
|
tos = COMMA.split(tosString).into_iter().map(|s| s.to_owned()).collect();
|
||||||
}
|
}
|
||||||
// if tosString != null {
|
// if tosString != null {
|
||||||
// tos = COMMA.split(tosString);
|
// tos = COMMA.split(tosString);
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
if let Some(ccString) = nv.get("cc"){
|
if let Some(ccString) = nv.get("cc"){
|
||||||
ccs = comma_regex.split(ccString).into_iter().map(|s| s.to_owned()).collect();
|
ccs = COMMA.split(ccString).into_iter().map(|s| s.to_owned()).collect();
|
||||||
}
|
}
|
||||||
// if ccString != null {
|
// if ccString != null {
|
||||||
// ccs = COMMA.split(ccString);
|
// ccs = COMMA.split(ccString);
|
||||||
// }
|
// }
|
||||||
if let Some(bccString) = nv.get("bcc"){
|
if let Some(bccString) = nv.get("bcc"){
|
||||||
bccs = comma_regex.split(bccString).into_iter().map(|s| s.to_owned()).collect();
|
bccs = COMMA.split(bccString).into_iter().map(|s| s.to_owned()).collect();
|
||||||
}
|
}
|
||||||
// if bccString != null {
|
// if bccString != null {
|
||||||
// bccs = COMMA.split(bccString);
|
// bccs = COMMA.split(bccString);
|
||||||
@@ -97,8 +103,8 @@ use super::{ParsedClientResult, ResultParser, EmailDoCoMoResultParser, EmailAddr
|
|||||||
}
|
}
|
||||||
return Some(ParsedClientResult::EmailResult(EmailAddressParsedRXingResult::with_details(tos, ccs, bccs, subject.to_owned(), body.to_owned())));
|
return Some(ParsedClientResult::EmailResult(EmailAddressParsedRXingResult::with_details(tos, ccs, bccs, subject.to_owned(), body.to_owned())));
|
||||||
} else {
|
} else {
|
||||||
let atext_alphanumeric = Regex::new("[a-zA-Z0-9@.!#$%&'*+\\-/=?^_`{|}~]+").unwrap();
|
// let atext_alphanumeric = Regex::new("[a-zA-Z0-9@.!#$%&'*+\\-/=?^_`{|}~]+").unwrap();
|
||||||
if !EmailDoCoMoResultParser::isBasicallyValidEmailAddress(&rawText,&atext_alphanumeric) {
|
if !EmailDoCoMoResultParser::isBasicallyValidEmailAddress(&rawText,&ATEXT_ALPHANUMERIC) {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
return Some(ParsedClientResult::EmailResult(EmailAddressParsedRXingResult::new(rawText)));
|
return Some(ParsedClientResult::EmailResult(EmailAddressParsedRXingResult::new(rawText)));
|
||||||
|
|||||||
@@ -26,6 +26,13 @@ use crate::RXingResult;
|
|||||||
|
|
||||||
use super::{ParsedClientResult, ResultParser, EmailAddressParsedRXingResult};
|
use super::{ParsedClientResult, ResultParser, EmailAddressParsedRXingResult};
|
||||||
|
|
||||||
|
use lazy_static::lazy_static;
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
static ref ATEXT_ALPHANUMERIC :Regex = Regex::new("[a-zA-Z0-9@.!#$%&'*+\\-/=?^_`{|}~]+").unwrap();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements the "MATMSG" email message entry format.
|
* Implements the "MATMSG" email message entry format.
|
||||||
*
|
*
|
||||||
@@ -34,7 +41,6 @@ use super::{ParsedClientResult, ResultParser, EmailAddressParsedRXingResult};
|
|||||||
* @author Sean Owen
|
* @author Sean Owen
|
||||||
*/
|
*/
|
||||||
pub fn parse(result: &RXingResult) -> Option<ParsedClientResult> {
|
pub fn parse(result: &RXingResult) -> Option<ParsedClientResult> {
|
||||||
let atext_alphanumeric = Regex::new("[a-zA-Z0-9@.!#$%&'*+\\-/=?^_`{|}~]+").unwrap();
|
|
||||||
|
|
||||||
let rawText = ResultParser::getMassagedText(result);
|
let rawText = ResultParser::getMassagedText(result);
|
||||||
if !rawText.starts_with("MATMSG:") {
|
if !rawText.starts_with("MATMSG:") {
|
||||||
@@ -43,7 +49,7 @@ use super::{ParsedClientResult, ResultParser, EmailAddressParsedRXingResult};
|
|||||||
let tos = ResultParser::match_do_co_mo_prefixed_field("TO:", &rawText)?;
|
let tos = ResultParser::match_do_co_mo_prefixed_field("TO:", &rawText)?;
|
||||||
|
|
||||||
for to in &tos {
|
for to in &tos {
|
||||||
if !isBasicallyValidEmailAddress(&to, &atext_alphanumeric) {
|
if !isBasicallyValidEmailAddress(&to, &ATEXT_ALPHANUMERIC) {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,12 @@
|
|||||||
|
|
||||||
use super::{GeoParsedRXingResult, ParsedClientResult, ResultParser};
|
use super::{GeoParsedRXingResult, ParsedClientResult, ResultParser};
|
||||||
|
|
||||||
|
use lazy_static::lazy_static;
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
static ref GEO_URL :regex::Regex = regex::Regex::new(GEO_URL_PATTERN).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
const GEO_URL_PATTERN: &'static str = "geo:([\\-0-9.]+),([\\-0-9.]+)(?:,([\\-0-9.]+))?(?:\\?(.*))?";
|
const GEO_URL_PATTERN: &'static str = "geo:([\\-0-9.]+),([\\-0-9.]+)(?:,([\\-0-9.]+))?(?:\\?(.*))?";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -39,9 +45,7 @@ const GEO_URL_PATTERN: &'static str = "geo:([\\-0-9.]+),([\\-0-9.]+)(?:,([\\-0-9
|
|||||||
pub fn parse(theRXingResult: &crate::RXingResult) -> Option<super::ParsedClientResult> {
|
pub fn parse(theRXingResult: &crate::RXingResult) -> Option<super::ParsedClientResult> {
|
||||||
let rawText = ResultParser::getMassagedText(theRXingResult);
|
let rawText = ResultParser::getMassagedText(theRXingResult);
|
||||||
|
|
||||||
let matcher = regex::Regex::new(GEO_URL_PATTERN).unwrap();
|
if let Some(captures) = GEO_URL.captures(&rawText.to_lowercase()) {
|
||||||
|
|
||||||
if let Some(captures) = matcher.captures(&rawText.to_lowercase()) {
|
|
||||||
let query = if let Some(q) = captures.get(4) {
|
let query = if let Some(q) = captures.get(4) {
|
||||||
q.as_str()
|
q.as_str()
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -31,6 +31,8 @@ use std::collections::HashMap;
|
|||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use urlencoding::decode;
|
use urlencoding::decode;
|
||||||
|
|
||||||
|
use lazy_static::lazy_static;
|
||||||
|
|
||||||
use crate::{exceptions::Exceptions, RXingResult};
|
use crate::{exceptions::Exceptions, RXingResult};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
@@ -90,7 +92,11 @@ use super::{
|
|||||||
|
|
||||||
pub type ParserFunction = dyn Fn(&RXingResult) -> Option<ParsedClientResult>;
|
pub type ParserFunction = dyn Fn(&RXingResult) -> Option<ParsedClientResult>;
|
||||||
|
|
||||||
const DIGITS: &'static str = "\\d+"; //= Pattern.compile("\\d+");
|
lazy_static! {
|
||||||
|
static ref DIGITS :Regex = Regex::new("\\d+").unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
// const DIGITS: &'static str = "\\d+"; //= Pattern.compile("\\d+");
|
||||||
const AMPERSAND: &'static str = "&"; // private static final Pattern AMPERSAND = Pattern.compile("&");
|
const AMPERSAND: &'static str = "&"; // private static final Pattern AMPERSAND = Pattern.compile("&");
|
||||||
const EQUALS: &'static str = "="; //private static final Pattern EQUALS = Pattern.compile("=");
|
const EQUALS: &'static str = "="; //private static final Pattern EQUALS = Pattern.compile("=");
|
||||||
const BYTE_ORDER_MARK: &'static str = "\u{feff}"; //private static final String BYTE_ORDER_MARK = "\ufeff";
|
const BYTE_ORDER_MARK: &'static str = "\u{feff}"; //private static final String BYTE_ORDER_MARK = "\ufeff";
|
||||||
@@ -229,8 +235,7 @@ pub fn parseHexDigit(c: char) -> i32 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn isStringOfDigits(value: &str, length: usize) -> bool {
|
pub fn isStringOfDigits(value: &str, length: usize) -> bool {
|
||||||
let matcher = Regex::new(DIGITS).unwrap();
|
!value.is_empty() && length > 0 && length == value.len() && DIGITS.is_match(value)
|
||||||
!value.is_empty() && length > 0 && length == value.len() && matcher.is_match(value)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn isSubstringOfDigits(value: &str, offset: usize, length: usize) -> bool {
|
pub fn isSubstringOfDigits(value: &str, offset: usize, length: usize) -> bool {
|
||||||
@@ -239,10 +244,9 @@ pub fn isSubstringOfDigits(value: &str, offset: usize, length: usize) -> bool {
|
|||||||
}
|
}
|
||||||
let max = offset as usize + length;
|
let max = offset as usize + length;
|
||||||
|
|
||||||
let matcher = Regex::new(DIGITS).unwrap();
|
|
||||||
let sub_seq = &value[offset as usize..max];
|
let sub_seq = &value[offset as usize..max];
|
||||||
|
|
||||||
let is_a_match = if let Some(mtch) = matcher.find(sub_seq) {
|
let is_a_match = if let Some(mtch) = DIGITS.find(sub_seq) {
|
||||||
if mtch.start() == 0 && mtch.end() == sub_seq.len() {
|
if mtch.start() == 0 && mtch.end() == sub_seq.len() {
|
||||||
true
|
true
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -28,18 +28,26 @@
|
|||||||
*/
|
*/
|
||||||
// public final class URIRXingResultParser extends RXingResultParser {
|
// public final class URIRXingResultParser extends RXingResultParser {
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
|
use lazy_static::lazy_static;
|
||||||
|
|
||||||
use crate::RXingResult;
|
use crate::RXingResult;
|
||||||
|
|
||||||
use super::{ParsedClientResult, ResultParser, URIParsedRXingResult};
|
use super::{ParsedClientResult, ResultParser, URIParsedRXingResult};
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
static ref ALLOWED_URI_CHARS :Regex = Regex::new( ALLOWED_URI_CHARS_PATTERN).expect("Regex patterns should always copile");
|
||||||
|
static ref USER_IN_HOST :Regex = Regex::new(":/*([^/@]+)@[^/]+").expect("Regex patterns should always copile");
|
||||||
|
static ref URL_WITH_PROTOCOL_PATTERN : Regex = Regex::new("[a-zA-Z][a-zA-Z0-9+-.]+:").unwrap();
|
||||||
|
static ref URL_WITHOUT_PROTOCOL_PATTERN :Regex = Regex::new("([a-zA-Z0-9\\-]+\\.){1,6}[a-zA-Z]{2,}(:\\d{1,5})?(/|\\?|$)").unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
const ALLOWED_URI_CHARS_PATTERN: &'static str = "[-._~:/?#\\[\\]@!$&'()*+,;=%A-Za-z0-9]+";
|
const ALLOWED_URI_CHARS_PATTERN: &'static str = "[-._~:/?#\\[\\]@!$&'()*+,;=%A-Za-z0-9]+";
|
||||||
const USER_IN_HOST: &'static str = ":/*([^/@]+)@[^/]+";
|
// const USER_IN_HOST: &'static str = ":/*([^/@]+)@[^/]+";
|
||||||
/// See http://www.ietf.org/rfc/rfc2396.txt
|
/// See http://www.ietf.org/rfc/rfc2396.txt
|
||||||
const URL_WITH_PROTOCOL_PATTERN: &'static str = "[a-zA-Z][a-zA-Z0-9+-.]+:";
|
// const URL_WITH_PROTOCOL_PATTERN: &'static str = "[a-zA-Z][a-zA-Z0-9+-.]+:";
|
||||||
/// (host name elements; allow up to say 6 domain elements), (maybe port), (query, path or nothing)
|
/// (host name elements; allow up to say 6 domain elements), (maybe port), (query, path or nothing)
|
||||||
const URL_WITHOUT_PROTOCOL_PATTERN: &'static str =
|
// const URL_WITHOUT_PROTOCOL_PATTERN: &'static str =
|
||||||
"([a-zA-Z0-9\\-]+\\.){1,6}[a-zA-Z]{2,}(:\\d{1,5})?(/|\\?|$)";
|
// "([a-zA-Z0-9\\-]+\\.){1,6}[a-zA-Z]{2,}(:\\d{1,5})?(/|\\?|$)";
|
||||||
|
|
||||||
pub fn parse(result: &RXingResult) -> Option<ParsedClientResult> {
|
pub fn parse(result: &RXingResult) -> Option<ParsedClientResult> {
|
||||||
let raw_text = ResultParser::getMassagedText(result);
|
let raw_text = ResultParser::getMassagedText(result);
|
||||||
@@ -71,11 +79,8 @@ pub fn parse(result: &RXingResult) -> Option<ParsedClientResult> {
|
|||||||
* to connect to yourbank.com at first glance.
|
* to connect to yourbank.com at first glance.
|
||||||
*/
|
*/
|
||||||
pub fn is_possibly_malicious_uri(uri: &str) -> bool {
|
pub fn is_possibly_malicious_uri(uri: &str) -> bool {
|
||||||
let allowed_chars_regex =
|
|
||||||
Regex::new(ALLOWED_URI_CHARS_PATTERN).expect("Regex patterns should always copile");
|
|
||||||
let user_in_host = Regex::new(USER_IN_HOST).expect("Regex patterns should always copile");
|
|
||||||
|
|
||||||
let allowed = if let Some(fnd) = allowed_chars_regex.find(uri){
|
let allowed = if let Some(fnd) = ALLOWED_URI_CHARS.find(uri){
|
||||||
if fnd.start() == 0 && fnd.end() == uri.len() {
|
if fnd.start() == 0 && fnd.end() == uri.len() {
|
||||||
true
|
true
|
||||||
}else {
|
}else {
|
||||||
@@ -84,7 +89,7 @@ pub fn is_possibly_malicious_uri(uri: &str) -> bool {
|
|||||||
}else{
|
}else{
|
||||||
false
|
false
|
||||||
};
|
};
|
||||||
let user = user_in_host.is_match(uri);
|
let user = USER_IN_HOST.is_match(uri);
|
||||||
|
|
||||||
!allowed || user
|
!allowed || user
|
||||||
}
|
}
|
||||||
@@ -94,16 +99,16 @@ pub fn is_basically_valid_uri(uri: &str) -> bool {
|
|||||||
// Quick hack check for a common case
|
// Quick hack check for a common case
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
let m = Regex::new(URL_WITH_PROTOCOL_PATTERN).expect("Regex patterns should always copile"); //.matcher(uri);
|
// let m = Regex::new(URL_WITH_PROTOCOL_PATTERN).expect("Regex patterns should always copile"); //.matcher(uri);
|
||||||
if let Some(found) = m.find(uri) {
|
if let Some(found) = URL_WITH_PROTOCOL_PATTERN.find(uri) {
|
||||||
if found.start() == 0 {
|
if found.start() == 0 {
|
||||||
// match at start only
|
// match at start only
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let m = Regex::new(URL_WITHOUT_PROTOCOL_PATTERN).expect("Regex patterns should always copile"); //.matcher(uri);
|
// let m = Regex::new(URL_WITHOUT_PROTOCOL_PATTERN).expect("Regex patterns should always copile"); //.matcher(uri);
|
||||||
if let Some(found) = m.find(uri) {
|
if let Some(found) = URL_WITHOUT_PROTOCOL_PATTERN.find(uri) {
|
||||||
if found.start() == 0 {
|
if found.start() == 0 {
|
||||||
// match at start only
|
// match at start only
|
||||||
true
|
true
|
||||||
|
|||||||
@@ -33,22 +33,35 @@ use std::convert::TryFrom;
|
|||||||
use encoding::all::encodings;
|
use encoding::all::encodings;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
|
|
||||||
|
use lazy_static::lazy_static;
|
||||||
|
|
||||||
use crate::RXingResult;
|
use crate::RXingResult;
|
||||||
|
|
||||||
use uriparse::URI;
|
use uriparse::URI;
|
||||||
|
|
||||||
use super::{AddressBookParsedRXingResult, ParsedClientResult, ResultParser};
|
use super::{AddressBookParsedRXingResult, ParsedClientResult, ResultParser};
|
||||||
|
|
||||||
const BEGIN_VCARD: &'static str = "(?i:BEGIN:VCARD)"; //, Pattern.CASE_INSENSITIVE);
|
lazy_static! {
|
||||||
const VCARD_LIKE_DATE: &'static str = "\\d{4}-?\\d{2}-?\\d{2}";
|
static ref BEGIN_VCARD :Regex= Regex::new("(?i:BEGIN:VCARD)").unwrap();
|
||||||
const CR_LF_SPACE_TAB: &'static str = "\r\n[ \t]";
|
static ref VCARD_LIKE_DATE : Regex = Regex::new("\\d{4}-?\\d{2}-?\\d{2}").unwrap();
|
||||||
const NEWLINE_ESCAPE: &'static str = "\\\\[nN]";
|
static ref CR_LF_SPACE_TAB : Regex = Regex::new("\r\n[ \t]").unwrap();
|
||||||
const VCARD_ESCAPES: &'static str = "\\\\([,;\\\\])";
|
static ref NEWLINE_ESCAPE : Regex = Regex::new("\\\\[nN]").unwrap();
|
||||||
const EQUALS: &'static str = "=";
|
static ref VCARD_ESCAPE : Regex = Regex::new("\\\\([,;\\\\])").unwrap();
|
||||||
|
static ref EQUALS : Regex = Regex::new("=").unwrap();
|
||||||
|
static ref UNESCAPED_SEMICOLONS : fancy_regex::Regex = fancy_regex::Regex::new("(?<!\\\\);+").unwrap();
|
||||||
|
static ref SEMICOLON_OR_COMMA : Regex = Regex::new("[;,]").unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
// const BEGIN_VCARD: &'static str = "(?i:BEGIN:VCARD)"; //, Pattern.CASE_INSENSITIVE);
|
||||||
|
// const VCARD_LIKE_DATE: &'static str = "\\d{4}-?\\d{2}-?\\d{2}";
|
||||||
|
// const CR_LF_SPACE_TAB: &'static str = "\r\n[ \t]";
|
||||||
|
// const NEWLINE_ESCAPE: &'static str = "\\\\[nN]";
|
||||||
|
// const VCARD_ESCAPES: &'static str = "\\\\([,;\\\\])";
|
||||||
|
// const EQUALS: &'static str = "=";
|
||||||
const SEMICOLON: &'static str = ";";
|
const SEMICOLON: &'static str = ";";
|
||||||
const UNESCAPED_SEMICOLONS: &'static str = "(?<!\\\\);+";
|
// const UNESCAPED_SEMICOLONS: &'static str = "(?<!\\\\);+";
|
||||||
const COMMA: &'static str = ",";
|
const COMMA: &'static str = ",";
|
||||||
const SEMICOLON_OR_COMMA: &'static str = "[;,]";
|
// const SEMICOLON_OR_COMMA: &'static str = "[;,]";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parses contact information formatted according to the VCard (2.1) format. This is not a complete
|
* Parses contact information formatted according to the VCard (2.1) format. This is not a complete
|
||||||
@@ -62,10 +75,10 @@ pub fn parse(result: &RXingResult) -> Option<ParsedClientResult> {
|
|||||||
// is doing just that, and we can't parse its contacts without this leniency.
|
// is doing just that, and we can't parse its contacts without this leniency.
|
||||||
let rawText = ResultParser::getMassagedText(result);
|
let rawText = ResultParser::getMassagedText(result);
|
||||||
|
|
||||||
let semicolon_comma_regex = Regex::new(SEMICOLON_OR_COMMA).unwrap();
|
// let semicolon_comma_regex = Regex::new(SEMICOLON_OR_COMMA).unwrap();
|
||||||
|
|
||||||
let rg = Regex::new(BEGIN_VCARD).unwrap();
|
// let rg = Regex::new(BEGIN_VCARD).unwrap();
|
||||||
let mtch = rg.find(&rawText)?;
|
let mtch = BEGIN_VCARD.find(&rawText)?;
|
||||||
// Matcher m = BEGIN_VCARD.matcher(rawText);
|
// Matcher m = BEGIN_VCARD.matcher(rawText);
|
||||||
if mtch.start() != 0 {
|
if mtch.start() != 0 {
|
||||||
return None;
|
return None;
|
||||||
@@ -120,7 +133,7 @@ pub fn parse(result: &RXingResult) -> Option<ParsedClientResult> {
|
|||||||
let geo = if geoString.is_none() {
|
let geo = if geoString.is_none() {
|
||||||
Vec::new()
|
Vec::new()
|
||||||
} else {
|
} else {
|
||||||
semicolon_comma_regex
|
SEMICOLON_OR_COMMA
|
||||||
.split(&geoString.unwrap()[0])
|
.split(&geoString.unwrap()[0])
|
||||||
.map(|x| x.to_owned())
|
.map(|x| x.to_owned())
|
||||||
.collect()
|
.collect()
|
||||||
@@ -163,11 +176,11 @@ pub fn matchVCardPrefixedField(
|
|||||||
let mut i = 0;
|
let mut i = 0;
|
||||||
let max = rawText.len();
|
let max = rawText.len();
|
||||||
|
|
||||||
let equals_regex = Regex::new(EQUALS).unwrap();
|
// let equals_regex = Regex::new(EQUALS).unwrap();
|
||||||
let unescaped_semis = fancy_regex::Regex::new(UNESCAPED_SEMICOLONS).unwrap();
|
// let unescaped_semis = fancy_regex::Regex::new(UNESCAPED_SEMICOLONS).unwrap();
|
||||||
let cr_lf_space_tab = Regex::new(CR_LF_SPACE_TAB).unwrap();
|
// let cr_lf_space_tab = Regex::new(CR_LF_SPACE_TAB).unwrap();
|
||||||
let newline_esc = Regex::new(NEWLINE_ESCAPE).unwrap();
|
// let newline_esc = Regex::new(NEWLINE_ESCAPE).unwrap();
|
||||||
let vcard_esc = Regex::new(VCARD_ESCAPES).unwrap();
|
// let vcard_esc = Regex::new(VCARD_ESCAPES).unwrap();
|
||||||
|
|
||||||
// At start or after newline, match prefix, followed by optional metadata
|
// At start or after newline, match prefix, followed by optional metadata
|
||||||
// (led by ;) ultimately ending in colon
|
// (led by ;) ultimately ending in colon
|
||||||
@@ -205,7 +218,7 @@ pub fn matchVCardPrefixedField(
|
|||||||
// }
|
// }
|
||||||
metadata.push(metadatum.to_owned());
|
metadata.push(metadatum.to_owned());
|
||||||
|
|
||||||
let metadatumTokens = equals_regex.splitn(metadatum, 2).collect::<Vec<&str>>();
|
let metadatumTokens = EQUALS.splitn(metadatum, 2).collect::<Vec<&str>>();
|
||||||
if metadatumTokens.len() > 1 {
|
if metadatumTokens.len() > 1 {
|
||||||
let key = metadatumTokens[0];
|
let key = metadatumTokens[0];
|
||||||
let value = metadatumTokens[1];
|
let value = metadatumTokens[1];
|
||||||
@@ -261,7 +274,7 @@ pub fn matchVCardPrefixedField(
|
|||||||
if quotedPrintable {
|
if quotedPrintable {
|
||||||
element = decodeQuotedPrintable(&element, quotedPrintableCharset);
|
element = decodeQuotedPrintable(&element, quotedPrintableCharset);
|
||||||
if parseFieldDivider {
|
if parseFieldDivider {
|
||||||
element = unescaped_semis
|
element = UNESCAPED_SEMICOLONS
|
||||||
.replace_all(&element, "\n")
|
.replace_all(&element, "\n")
|
||||||
.to_mut()
|
.to_mut()
|
||||||
.trim()
|
.trim()
|
||||||
@@ -270,19 +283,19 @@ pub fn matchVCardPrefixedField(
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if parseFieldDivider {
|
if parseFieldDivider {
|
||||||
element = unescaped_semis
|
element = UNESCAPED_SEMICOLONS
|
||||||
.replace_all(&element, "\n")
|
.replace_all(&element, "\n")
|
||||||
.to_mut()
|
.to_mut()
|
||||||
.trim()
|
.trim()
|
||||||
.to_owned();
|
.to_owned();
|
||||||
// element = UNESCAPED_SEMICOLONS.matcher(element).replaceAll("\n").trim();
|
// element = UNESCAPED_SEMICOLONS.matcher(element).replaceAll("\n").trim();
|
||||||
}
|
}
|
||||||
element = cr_lf_space_tab
|
element = CR_LF_SPACE_TAB
|
||||||
.replace_all(&element, "")
|
.replace_all(&element, "")
|
||||||
.to_mut()
|
.to_mut()
|
||||||
.to_owned();
|
.to_owned();
|
||||||
element = newline_esc.replace_all(&element, "\n").to_mut().to_owned();
|
element = NEWLINE_ESCAPE.replace_all(&element, "\n").to_mut().to_owned();
|
||||||
element = vcard_esc.replace_all(&element, "$1").to_mut().to_owned();
|
element = VCARD_ESCAPE.replace_all(&element, "$1").to_mut().to_owned();
|
||||||
// element = CR_LF_SPACE_TAB.matcher(element).replaceAll("");
|
// element = CR_LF_SPACE_TAB.matcher(element).replaceAll("");
|
||||||
// element = NEWLINE_ESCAPE.matcher(element).replaceAll("\n");
|
// element = NEWLINE_ESCAPE.matcher(element).replaceAll("\n");
|
||||||
// element = VCARD_ESCAPES.matcher(element).replaceAll("$1");
|
// element = VCARD_ESCAPES.matcher(element).replaceAll("$1");
|
||||||
@@ -516,8 +529,8 @@ fn toTypes(lists: Option<Vec<Vec<String>>>) -> Vec<String> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn isLikeVCardDate(value: &str) -> bool {
|
fn isLikeVCardDate(value: &str) -> bool {
|
||||||
let rg = Regex::new(VCARD_LIKE_DATE).unwrap();
|
// let rg = Regex::new(VCARD_LIKE_DATE).unwrap();
|
||||||
let matches = if let Some(mtch) = rg.find(value) {
|
let matches = if let Some(mtch) = VCARD_LIKE_DATE.find(value) {
|
||||||
mtch.start() == 0 && mtch.end() == value.len()
|
mtch.start() == 0 && mtch.end() == value.len()
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
|
|||||||
@@ -29,6 +29,13 @@ use crate::{
|
|||||||
|
|
||||||
use super::ParsedClientResult;
|
use super::ParsedClientResult;
|
||||||
|
|
||||||
|
use lazy_static::lazy_static;
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
static ref IOQ_MATCHER : Regex = Regex::new(IOQ).unwrap();
|
||||||
|
static ref AZ09_MATCHER: Regex = Regex::new(AZ09).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Detects a result that is likely a vehicle identification number.
|
* Detects a result that is likely a vehicle identification number.
|
||||||
*
|
*
|
||||||
@@ -38,12 +45,11 @@ pub fn parse(result: &RXingResult) -> Option<ParsedClientResult> {
|
|||||||
if result.getBarcodeFormat() != &BarcodeFormat::CODE_39 {
|
if result.getBarcodeFormat() != &BarcodeFormat::CODE_39 {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
let ioq_matcher = Regex::new(IOQ).unwrap();
|
|
||||||
let az09_matcher = Regex::new(AZ09).unwrap();
|
|
||||||
let raw_text_res = result.getText().trim();
|
let raw_text_res = result.getText().trim();
|
||||||
let raw_text = ioq_matcher.replace_all(raw_text_res, "").to_string();
|
let raw_text = IOQ_MATCHER.replace_all(raw_text_res, "").to_string();
|
||||||
// rawText = IOQ.matcher(rawText).replaceAll("").trim();
|
// rawText = IOQ.matcher(rawText).replaceAll("").trim();
|
||||||
if let None = az09_matcher.find(&raw_text) {
|
if let None = AZ09_MATCHER.find(&raw_text) {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
// if !AZ09.matcher(rawText).matches() {
|
// if !AZ09.matcher(rawText).matches() {
|
||||||
|
|||||||
Reference in New Issue
Block a user