Subversion Repositories oidplus

Rev

Rev 379 | Rev 392 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. <?php
  2.  
  3. /*
  4.  * OIDplus 2.0
  5.  * Copyright 2019 Daniel Marschall, ViaThinkSoft
  6.  *
  7.  * Licensed under the Apache License, Version 2.0 (the "License");
  8.  * you may not use this file except in compliance with the License.
  9.  * You may obtain a copy of the License at
  10.  *
  11.  *     http://www.apache.org/licenses/LICENSE-2.0
  12.  *
  13.  * Unless required by applicable law or agreed to in writing, software
  14.  * distributed under the License is distributed on an "AS IS" BASIS,
  15.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16.  * See the License for the specific language governing permissions and
  17.  * limitations under the License.
  18.  */
  19.  
  20. function insertWhitespace($str, $index) {
  21.         return substr($str, 0, $index) . ' ' . substr($str, $index);
  22. }
  23.  
  24. function js_escape($data) {
  25.         // TODO.... json_encode??
  26.         $data = str_replace('\\', '\\\\', $data);
  27.         $data = str_replace('\'', '\\\'', $data);
  28.         return "'" . $data . "'";
  29. }
  30.  
  31. function trim_br($html) {
  32.         $count = 0;
  33.         do { $html = preg_replace('@^\s*<\s*br\s*/{0,1}\s*>@isU', '', $html, -1, $count); } while ($count > 0); // left trim
  34.         do { $html = preg_replace('@<\s*br\s*/{0,1}\s*>\s*$@isU', '', $html, -1, $count); } while ($count > 0); // right trim
  35.         return $html;
  36. }
  37.  
  38. function verify_private_public_key($privKey, $pubKey) {
  39.         try {
  40.                 if (empty($privKey)) return false;
  41.                 if (empty($pubKey)) return false;
  42.                 $data = 'TEST';
  43.                 $encrypted = '';
  44.                 $decrypted = '';
  45.                 if (!@openssl_public_encrypt($data, $encrypted, $pubKey)) return false;
  46.                 if (!@openssl_private_decrypt($encrypted, $decrypted, $privKey)) return false;
  47.                 return $decrypted == $data;
  48.         } catch (Exception $e) {
  49.                 return false;
  50.         }
  51. }
  52.  
  53. function smallhash($data) { // get 31 bits from SHA1. Values 0..2147483647
  54.         return (hexdec(substr(sha1($data),-4*2)) & 0x7FFFFFFF);
  55. }
  56.  
  57. function split_firstname_lastname($name) {
  58.         $ary = explode(' ', $name);
  59.         $last_name = array_pop($ary);
  60.         $first_name = implode(' ', $ary);
  61.         return array($first_name, $last_name);
  62. }
  63.  
  64. function originHeaders() {
  65.         // CORS
  66.         // Author: Till Wehowski
  67.  
  68.         header("Access-Control-Allow-Credentials: true");
  69.         header("Access-Control-Allow-Origin: ".strip_tags(((isset($_SERVER['HTTP_ORIGIN'])) ? $_SERVER['HTTP_ORIGIN'] : "*")));
  70.  
  71.         header("Access-Control-Allow-Headers: If-None-Match, X-Requested-With, Origin, X-Frdlweb-Bugs, Etag, X-Forgery-Protection-Token, X-CSRF-Token");
  72.  
  73.         if (isset($_SERVER['HTTP_ORIGIN'])) {
  74.                 header('X-Frame-Options: ALLOW-FROM '.$_SERVER['HTTP_ORIGIN']);
  75.         } else {
  76.                 header_remove("X-Frame-Options");
  77.         }
  78.  
  79.         $expose = array('Etag', 'X-CSRF-Token');
  80.         foreach (headers_list() as $num => $header) {
  81.                 $h = explode(':', $header);
  82.                 $expose[] = trim($h[0]);
  83.         }
  84.         header("Access-Control-Expose-Headers: ".implode(',',$expose));
  85.  
  86.         header("Vary: Origin");
  87. }
  88.  
  89. function get_calling_function() {
  90.         $ex = new Exception();
  91.         $trace = $ex->getTrace();
  92.         if (!isset($trace[2])) return _L('(main)');
  93.         $final_call = $trace[2];
  94.         return $final_call['file'].':'.$final_call['line'].'/'.$final_call['function'].'()';
  95. }
  96.  
  97. if (!function_exists('mb_wordwrap')) {
  98.         function mb_wordwrap($str, $width = 75, $break = "\n", $cut = false) {
  99.                 // https://stackoverflow.com/a/4988494/488539
  100.                 $lines = explode($break, $str);
  101.                 foreach ($lines as &$line) {
  102.                         $line = rtrim($line);
  103.                         if (mb_strlen($line) <= $width) {
  104.                                 continue;
  105.                         }
  106.                         $words = explode(' ', $line);
  107.                         $line = '';
  108.                         $actual = '';
  109.                         foreach ($words as $word) {
  110.                                 if (mb_strlen($actual.$word) <= $width) {
  111.                                         $actual .= $word.' ';
  112.                                 } else {
  113.                                         if ($actual != '') {
  114.                                                 $line .= rtrim($actual).$break;
  115.                                         }
  116.                                         $actual = $word;
  117.                                         if ($cut) {
  118.                                                 while (mb_strlen($actual) > $width) {
  119.                                                         $line .= mb_substr($actual, 0, $width).$break;
  120.                                                         $actual = mb_substr($actual, $width);
  121.                                                 }
  122.                                         }
  123.                                         $actual .= ' ';
  124.                                 }
  125.                         }
  126.                         $line .= trim($actual);
  127.                 }
  128.                 return implode($break, $lines);
  129.         }
  130. }
  131.  
  132. function httpOutWithETag($out, $contentType, $filename='') {
  133.         $etag = md5($out);
  134.         header("Etag: $etag");
  135.         header("Content-MD5: $etag"); // RFC 2616 clause 14.15
  136.         if (isset($_SERVER['HTTP_IF_NONE_MATCH']) && (trim($_SERVER['HTTP_IF_NONE_MATCH']) == $etag)) {
  137.                 header("HTTP/1.1 304 Not Modified");
  138.         } else {
  139.                 header("Content-Type: $contentType");
  140.                 if (!empty($filename)) {
  141.                         header('Content-Disposition:inline; filename="'.$filename.'"');
  142.                 }
  143.                 echo $out;
  144.         }
  145.         die();
  146. }
  147.  
  148. function my_vsprintf($str, $args) {
  149.         $n = 1;
  150.         foreach ($args as $val) {
  151.                 $str = str_replace("%$n", $val, $str);
  152.                 $n++;
  153.         }
  154.         $str = str_replace("%%", "%", $str);
  155.         return $str;
  156. }
  157.  
  158. function _L($str, ...$sprintfArgs) {
  159.         $lang = OIDplus::getCurrentLang();
  160.  
  161.         static $translation_array = array();
  162.         static $translation_loaded = null;
  163.         if ($lang != $translation_loaded) {
  164.                 $good = true;
  165.                 if (strpos($lang,'/') !== false) $good = false; // prevent attack (but actually, the sanitization in getCurrentLang should work)
  166.                 if (strpos($lang,'\\') !== false) $good = false; // prevent attack (but actually, the sanitization in getCurrentLang should work)
  167.                 if (strpos($lang,'..') !== false) $good = false; // prevent attack (but actually, the sanitization in getCurrentLang should work)
  168.                 $translation_file = __DIR__.'/../plugins/language/'.$lang.'/messages.xml';
  169.                 if ($good && !file_exists($translation_file)) $good = false;
  170.                 if ($good) {
  171.                         $xml = simplexml_load_string(file_get_contents($translation_file));
  172.                         foreach ($xml->message as $msg) {
  173.                                 $src = trim($msg->source->__toString());
  174.                                 $dst = trim($msg->target->__toString());
  175.                                 $translation_array[$src] = $dst;
  176.                         }
  177.                         $translation_loaded = $lang;
  178.                 }
  179.         }
  180.  
  181.         if ($lang != $translation_loaded) {
  182.                 // Something bad happened (e.g. attack or message file not found)
  183.                 $res = $str;
  184.         } else {
  185.                 $res = isset($translation_array[$str]) && !empty($translation_array[$str]) ? $translation_array[$str] : $str;
  186.         }
  187.  
  188.         $res = str_replace('###', OIDplus::baseConfig()->getValue('TABLENAME_PREFIX', ''), $res);
  189.  
  190.         $res = my_vsprintf($res, $sprintfArgs);
  191.  
  192.         return $res;
  193. }
  194.  
  195. function extractHtmlContents($cont) {
  196.         // make sure the program works even if the user provided HTML is not UTF-8
  197.         $cont = iconv(mb_detect_encoding($cont, mb_detect_order(), true), 'UTF-8//IGNORE', $cont);
  198.         $bom = pack('H*','EFBBBF');
  199.         $cont = preg_replace("/^$bom/", '', $cont);
  200.  
  201.         $out_js = '';
  202.         $m = array();
  203.         preg_match_all('@<script[^>]*>(.+)</script>@ismU', $cont, $m);
  204.         foreach ($m[1] as $x) {
  205.                 $out_js = $x . "\n\n";
  206.         }
  207.  
  208.         $out_css = '';
  209.         $m = array();
  210.         preg_match_all('@<style[^>]*>(.+)</style>@ismU', $cont, $m);
  211.         foreach ($m[1] as $x) {
  212.                 $out_css = $x . "\n\n";
  213.         }
  214.  
  215.         $out_html = $cont;
  216.         $out_html = preg_replace('@^(.+)<body[^>]*>@isU', '', $out_html);
  217.         $out_html = preg_replace('@</body>.+$@isU', '', $out_html);
  218.         $out_html = preg_replace('@<title>.+</title>@isU', '', $out_html);
  219.         $out_html = preg_replace('@<h1>.+</h1>@isU', '', $out_html, 1);
  220.         $out_html = preg_replace('@<script[^>]*>(.+)</script>@ismU', '', $out_html);
  221.         $out_html = preg_replace('@<style[^>]*>(.+)</style>@ismU', '', $out_html);
  222.  
  223.         return array($out_html, $out_js, $out_css);
  224. }