diff --git a/EmailObfuscation.info.json b/EmailObfuscation.info.json index 5adfe0d..f824324 100644 --- a/EmailObfuscation.info.json +++ b/EmailObfuscation.info.json @@ -1,6 +1,6 @@ { "title": "Email Obfuscation (EMO)", - "version": 131, + "version": 132, "summary": "Email Obfuscation module for email addresses with 64 base crypting.", "author": "Jukka Hankaniemi (Roope)", "href": "https://github.com/BlowbackAgency/EmailObfuscation", diff --git a/EmailObfuscation.module b/EmailObfuscation.module index bcce1ca..cb51041 100644 --- a/EmailObfuscation.module +++ b/EmailObfuscation.module @@ -4,7 +4,7 @@ * * Email Obfuscation module for email addresses with 64 base crypting. * - * @version 1.3.1 + * @version 1.3.2 * @copyright Blowback https://github.com/BlowbackDesign * @license MIT https://opensource.org/license/mit/ * @@ -304,12 +304,11 @@ class EmailObfuscation extends WireData implements Module, ConfigurableModule } /** - * obfuscate email addresses at given (html) string - * + * get skip patterns for obfuscation */ - private function obfuscate($html) + private function getSkipPatterns() { - $skip = array( + return array( ' "((?:))", ' "((?:))", ' "((?:))", @@ -320,8 +319,17 @@ class EmailObfuscation extends WireData implements Module, ConfigurableModule 'label' => "((?:label=['\"]).*(?:['\"]))", 'href=' => "((?:href=['\"](?!mailto:)(?:[a-z]+:|\/|\\#)).*(?:['\"]))", 'data-' => "((?:data-[A-Z0-9.-]+=['\"]).*(?:['\"]))", + 'https' => "(https?://[^\s<>\"']+?)", ); + } + /** + * obfuscate email addresses at given (html) string + * + */ + private function obfuscate($html) + { + $skip = $this->getSkipPatterns(); $tags = "#" . implode('|', $skip) . "#isUu"; $mailto = "#]*mailto:([^'\"@]+)@([^'\"]+)['\"][^>]*>(.*)<\/a>#isUu"; $output = ""; @@ -471,6 +479,108 @@ class EmailObfuscation extends WireData implements Module, ConfigurableModule if($this->debug) $this->debugTime += Debug::timer($time); } + /** + * test how skip patterns split given html + * + * Usage: + * + * $emo = $modules->get('EmailObfuscation'); + * $result = $emo->testObfuscate('Contact'); + * // Returns: ['input' => '...', 'output' => '...', 'parts' => [['action' => 'SKIP|OBFUSCATE', 'content' => '...'], ...]] + */ + public function testObfuscate($html) + { + $skip = $this->getSkipPatterns(); + $tags = "#" . implode('|', $skip) . "#isUu"; + $parts = preg_split($tags, $html, 0, PREG_SPLIT_NO_EMPTY|PREG_SPLIT_DELIM_CAPTURE); + + $results = array( + 'input' => $html, + 'output' => $this->obfuscate($html), + 'parts' => array(), + ); + foreach($parts as $i => $str) { + $skipped = in_array(substr($str, 0, 5), array_keys($skip)); + $results['parts'][] = array( + 'action' => $skipped ? 'SKIP' : 'OBFUSCATE', + 'content' => $str, + ); + } + + return $results; + } + + /** + * run built-in test cases + * + * Usage: + * + * $emo = $modules->get('EmailObfuscation'); + * $results = $emo->testObfuscateWithCases(); + * // Returns: ['case name' => ['pass' => bool, 'input' => '...', 'output' => '...', 'expected' => '...'], ...] + */ + public function testObfuscateWithCases() + { + // Use fixed settings for deterministic output + $originalUseFixedKey = $this->useFixedKey; + $originalFixedKey = $this->fixedKey; + $originalKey = $this->key; + $originalNoscript = $this->noscript; + $originalMailto = $this->mailto; + $this->useFixedKey = true; + $this->fixedKey = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_.'; + $this->key = null; + $this->noscript = 'Enable JavaScript to view protected content.'; + $this->mailto = true; + + $cases = array( + 'plain email' => array( + 'input' => 'Contact us at test@example.com for help.', + 'expect' => 'Contact us at for help.', + ), + 'mailto link' => array( + 'input' => 'test@example.com', + 'expect' => '', + ), + 'url with email-like path' => array( + 'input' => 'https://example.com/user@domain.com', + 'expect' => 'https://example.com/user@domain.com', + ), + 'email query parameter' => array( + 'input' => 'https://example.com/?email=user@example.com', + 'expect' => 'https://example.com/?email=user@example.com', + ), + 'multiple emails' => array( + 'input' => 'Contact alice@example.com or bob@example.com for help.', + 'expect' => 'Contact or for help.', + ), + ); + + $results = array(); + foreach($cases as $name => $case) { + $this->addrCount = 0; + $this->address = array(); + $this->addressData = array(); + + $output = $this->obfuscate($case['input']); + $results[$name] = array( + 'pass' => ($output === $case['expect']), + 'input' => $case['input'], + 'output' => $output, + 'expected' => $case['expect'], + ); + } + + // Restore original settings + $this->useFixedKey = $originalUseFixedKey; + $this->fixedKey = $originalFixedKey; + $this->key = $originalKey; + $this->noscript = $originalNoscript; + $this->mailto = $originalMailto; + + return $results; + } + /** * sets fixedKey value to module config when module is saved *