/** * @see \wcf\form\IForm::validate() */ public function validate() { AbstractForm::validate(); if (empty($this->masterPassword)) { throw new UserInputException('masterPassword'); } // check password security if (mb_strlen($this->masterPassword) < 12) { throw new UserInputException('masterPassword', 'notSecure'); } // digits if (!Regex::compile('\\d')->match($this->masterPassword)) { throw new UserInputException('masterPassword', 'notSecure'); } // latin characters (lower-case) if (!Regex::compile('[a-z]')->match($this->masterPassword)) { throw new UserInputException('masterPassword', 'notSecure'); } // latin characters (upper-case) if (!Regex::compile('[A-Z]')->match($this->masterPassword)) { throw new UserInputException('masterPassword', 'notSecure'); } // password equals username if ($this->masterPassword == WCF::getUser()->username) { throw new UserInputException('masterPassword', 'notSecure'); } // confirm master password if (empty($this->confirmMasterPassword)) { throw new UserInputException('confirmMasterPassword'); } if ($this->confirmMasterPassword != $this->masterPassword) { throw new UserInputException('confirmMasterPassword', 'notEqual'); } }
/** * @see \wcf\system\bbcode\highlighter\Highlighter::highlightKeywords() */ protected function highlightKeywords($string) { $string = Regex::compile('\\$([^\\$]*)\\$', Regex::DOT_ALL)->replace($string, '<span class="hlKeywords2">\\0</span>'); $string = Regex::compile('(\\\\(?:[a-z]+))(\\[[^\\]\\\\]+\\])?(\\{[^\\}]*\\})?', Regex::CASE_INSENSITIVE)->replace($string, '<span class="hlKeywords3">\\1</span><span class="hlKeywords4">\\2</span><span class="hlKeywords1">\\3</span>'); $string = str_replace('\\\\', '<span class="hlKeywords3">\\\\</span>', $string); return $string; }
/** * @see \wcf\system\bbcode\highlighter\Highlighter::highlight() */ public function highlight($code) { // add starting php tag $phpTagsAdded = false; if (mb_strpos($code, '<?') === false) { $phpTagsAdded = true; $code = '<?php ' . $code . ' ?>'; } // do highlight $highlightedCode = highlight_string($code, true); // clear code $highlightedCode = str_replace('<code>', '', $highlightedCode); $highlightedCode = str_replace('</code>', '', $highlightedCode); // remove added php tags if ($phpTagsAdded) { $regex = new Regex('([^\\2]*)(<\\?php )(.*)( .*\\?>)([^\\4]*)', Regex::CASE_INSENSITIVE | Regex::DOT_ALL); $highlightedCode = $regex->replace($highlightedCode, '\\1\\3\\5'); } // remove breaks $highlightedCode = str_replace("\n", "", $highlightedCode); $highlightedCode = str_replace('<br />', "\n", $highlightedCode); // get tabs back $highlightedCode = str_replace(' ', "\t", $highlightedCode); // replace non breaking space with normal space, white-space is preserved by CSS $highlightedCode = str_replace(' ', " ", $highlightedCode); // convert colors to classes $highlightedCode = strtr($highlightedCode, self::$colorToClass); // replace double quotes by entity return Regex::compile('(?<!\\<span class=)"(?!\\>)')->replace($highlightedCode, '"'); }
/** * @see \wcf\system\bbcode\highlighter\Highlighter::highlightComments() */ protected function highlightComments($string) { $string = parent::highlightComments($string); // highlight template tags $string = Regex::compile('\\{(?=\\S).+?(?<=\\S)\\}', Regex::DOT_ALL)->replace($string, '<span class="hlKeywords3">\\0</span>'); return $string; }
/** * @see \wcf\system\bbcode\highlighter\Highlighter::cacheQuotes() */ protected function cacheQuotes($string) { $string = parent::cacheQuotes($string); // highlight CDATA-Tags as quotes $string = Regex::compile('<!\\[CDATA\\[.*?\\]\\]>', Regex::DOT_ALL)->replace($string, new Callback(function (array $matches) { return StringStack::pushToStringStack('<span class="hlQuotes">' . StringUtil::encodeHTML($matches[0]) . '</span>', 'highlighterQuotes'); })); return $string; }
/** * Checks whether this provider matches the given URL. * * @param string $url * @return boolean */ public function matches($url) { $lines = explode("\n", StringUtil::unifyNewlines($this->regex)); foreach ($lines as $line) { if (Regex::compile($line)->match($url)) { return true; } } return false; }
/** * Checks whether this question matches the given message. * * @param string $message * @return boolean */ public function matches($message) { $lines = explode("\n", \wcf\util\StringUtil::unifyNewlines($this->questionMessage)); foreach ($lines as $line) { if (\wcf\system\Regex::compile($line)->match($message)) { return true; } } return false; }
/** * Handles the saved event. * * @param array $parameter */ protected function saved(array $parameter) { // get message, check by difference is quickreply or postadd $message = $parameter == null ? $this->eventObj->text : $parameter['message']->message; //if (!\wcf\system\Regex::compile('(^Butler.*$)')->match($message, true)) return; // get cached questions from cache, filter it by array functions, easier then foreach $questions = \wbb\data\post\butler\question\QuestionCache::getInstance()->getQuestions(); $questions = array_filter(array_map(function ($question) use($message) { if (!\wcf\system\Regex::compile(sprintf('(^%s.*$)', empty($question->prefixUsername) ? 'Butler' : $question->prefixUsername))->match($message, true)) { return false; } else { return $question->matches($message); } }, $questions), function ($value) { if ($value) { return $value; } }); // check if a value is given, otherwise abort continue of function if ($questions == null) { return; } else { $question = \wbb\data\post\butler\question\QuestionCache::getInstance()->getQuestionByID(array_rand($questions, 1)); } // get cached answers from cache, try to get only assigned answers $answers = \wbb\data\post\butler\answer\AnswerCache::getInstance()->getAnswers(); $answers = $answers[$question->questionID]; // check if a value is given and declare variable on success, otherwise abort function if ($answers == null) { return; } else { $answer = $answers[array_rand($answers, 1)]; } $threadID = 0; if ($parameter == null) { $threadActionObject = $this->eventObj->objectAction->getReturnValues(); $threadID = $threadActionObject['returnValues']->threadID; } else { $threadID = $this->eventObj->getContainer()->threadID; } $author = null; if ($question->prefixUserID > 0) { $author = \wcf\data\user\User::getUsers(array($question->prefixUserID)); if (count($author) == 1) { $author = array_shift($author); } } $postData = array('threadID' => $threadID, 'userID' => $question->prefixUserID == 0 ? null : $question->prefixUserID, 'username' => $author == null ? empty($question->prefixUsername) ? 'Butler' : $question->prefixUsername : $author->username, 'message' => $answer->getFormattedMessage(), 'time' => TIME_NOW, 'enableSmilies' => $answer->enableSmilies, 'enableHtml' => $answer->enableHtml, 'enableBBCodes' => $answer->enableBBCodes, 'showSignature' => 0); $objectAction = new \wbb\data\post\PostAction(array(), 'create', array('data' => $postData)); $objectAction->executeAction(); }
/** * Parses controller name. */ protected function parseController() { if ($this->controller === null) { $this->controller = ''; // resolve application and controller if ($this->menuItemController) { $parts = explode('\\', $this->menuItemController); $this->application = array_shift($parts); $menuItemController = array_pop($parts); // drop controller suffix $this->controller = Regex::compile('(Action|Form|Page)$')->replace($menuItemController, ''); } } }
/** * Gets the package_update.xml from an update server. * * @param wcf\data\package\update\server\PackageUpdateServer $updateServer */ protected function getPackageUpdateXML(PackageUpdateServer $updateServer) { $authData = $updateServer->getAuthData(); $settings = array(); if ($authData) $settings['auth'] = $authData; $postData = array( 'lastUpdateTime' => $updateServer->lastUpdateTime ); // append auth code if set and update server resolves to woltlab.com if (PACKAGE_SERVER_AUTH_CODE && Regex::compile('^https?://[a-z]+.woltlab.com/')->match($updateServer->serverURL)) { $postData['authCode'] = PACKAGE_SERVER_AUTH_CODE; } $request = new HTTPRequest($updateServer->serverURL, $settings, $postData); try { $request->execute(); $reply = $request->getReply(); } catch (SystemException $e) { $reply = $request->getReply(); if ($reply['statusCode'] == 401) { throw new PackageUpdateAuthorizationRequiredException($updateServer['packageUpdateServerID'], $updateServer['server'], $reply); } throw new SystemException(WCF::getLanguage()->get('wcf.acp.packageUpdate.error.listNotFound') . ' ('.reset($reply['headers']).')'); } // parse given package update xml $allNewPackages = $this->parsePackageUpdateXML($reply['body']); unset($request, $reply); // save packages if (!empty($allNewPackages)) { $this->savePackageUpdates($allNewPackages, $updateServer->packageUpdateServerID); } unset($allNewPackages); // update server status $updateServerEditor = new PackageUpdateServerEditor($updateServer); $updateServerEditor->update(array( 'lastUpdateTime' => TIME_NOW, 'status' => 'online', 'errorMessage' => '' )); }
/** * @see wcf\form\IForm::validate() */ public function validate() { ACPForm::validate(); if (empty($this->masterPassword)) { throw new UserInputException('masterPassword'); } // check password security if (StringUtil::length($this->masterPassword) < 8) { throw new UserInputException('masterPassword', 'notSecure'); } // digits if (!Regex::compile('\\d')->match($this->masterPassword)) { throw new UserInputException('masterPassword', 'notSecure'); } // latin characters (lower-case) if (!Regex::compile('[a-z]')->match($this->masterPassword)) { throw new UserInputException('masterPassword', 'notSecure'); } // latin characters (upper-case) if (!Regex::compile('[A-Z]')->match($this->masterPassword)) { throw new UserInputException('masterPassword', 'notSecure'); } // special characters if (!Regex::compile('[^0-9a-zA-Z]')->match($this->masterPassword)) { throw new UserInputException('masterPassword', 'notSecure'); } // password equals username if ($this->masterPassword == WCF::getUser()->username) { throw new UserInputException('masterPassword', 'notSecure'); } // search for identical admin passwords $sql = "SELECT\tpassword, salt\n\t\t\tFROM\twcf" . WCF_N . "_user\n\t\t\tWHERE\tuserID IN (\n\t\t\t\t\tSELECT\tuserID\n\t\t\t\t\tFROM\twcf" . WCF_N . "_user_to_group\n\t\t\t\t\tWHERE\tgroupID = 4\n\t\t\t\t)"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(); while ($row = $statement->fetchArray()) { if (StringUtil::getDoubleSaltedHash($this->masterPassword, $row['salt']) == $row['password']) { throw new UserInputException('masterPassword', 'notSecure'); } } // confirm master password if (empty($this->confirmMasterPassword)) { throw new UserInputException('confirmMasterPassword'); } if ($this->confirmMasterPassword != $this->masterPassword) { throw new UserInputException('confirmMasterPassword', 'notEqual'); } }
/** * Returns true if the given user input is an answer to this question. * * @param string $answer * @return boolean */ public function isAnswer($answer) { $answers = explode("\n", StringUtil::unifyNewlines(WCF::getLanguage()->get($this->answers))); foreach ($answers as $__answer) { if (mb_substr($__answer, 0, 1) == '~' && mb_substr($__answer, -1, 1) == '~') { if (Regex::compile(mb_substr($__answer, 1, mb_strlen($__answer) - 2))->match($answer)) { return true; } continue; } else { if ($__answer == $answer) { return true; } } } return false; }
/** * @see \wcf\form\IForm::validate() */ public function validate() { parent::validate(); // validate fields if (empty($this->title)) { throw new UserInputException('title'); } if (empty($this->regex)) { throw new UserInputException('regex'); } if (empty($this->html)) { throw new UserInputException('html'); } $lines = explode("\n", StringUtil::unifyNewlines($this->regex)); foreach ($lines as $line) { if (!Regex::compile($line)->isValid()) { throw new UserInputException('regex', 'notValid'); } } }
/** * @see wcf\system\database\editor\DatabaseEditor::getColumns() */ public function getColumns($tableName) { $columns = array(); $sql = "SHOW COLUMNS FROM ".$tableName; $statement = $this->dbObj->prepareStatement($sql); $statement->execute(); while ($row = $statement->fetchArray()) { $typeMatches = Regex::compile('([a-z]+)\(([0-9]+)\)', Regex::CASE_INSENSITIVE)->match($row['Type']); $columns[] = array('name' => $row['Field'], 'data' => array( 'type' => $typeMatches[1], 'length' => $typeMatches[2], 'notNull' => (($row['Null'] == 'YES') ? true : false), 'key' => (($row['Key'] == 'PRI') ? 'PRIMARY' : (($row['Key'] == 'UNI') ? 'UNIQUE' : '')), 'default' => $row['Default'], 'autoIncrement' => ($row['Extra'] == 'auto_increment' ? true : false) )); } return $columns; }
/** * @see \wcf\system\bbcode\highlighter\Highlighter::highlight() */ public function highlight($code) { // add starting php tag $phpTagsAdded = false; if (mb_strpos($code, '<?') === false) { $phpTagsAdded = true; $code = '<?php ' . $code . ' ?>'; } // do highlight $highlightedCode = highlight_string($code, true); // clear code $highlightedCode = str_replace('<code>', '', $highlightedCode); $highlightedCode = str_replace('</code>', '', $highlightedCode); // remove added php tags if ($phpTagsAdded) { // the opening and closing PHP tags were added previously, hence we actually do // know that the first (last for the closing tag) occurence is the one inserted // by us. The previously used regex was bad because it was significantly slower // and could easily hit the backtrace limit for larger inputs $openingTag = mb_strpos($highlightedCode, '<?php '); $closingTag = mb_strrpos($highlightedCode, '?>'); $tmp = mb_substr($highlightedCode, 0, $openingTag); $tmp .= mb_substr($highlightedCode, $openingTag + 14, $closingTag - $openingTag - 14); $tmp .= mb_substr($highlightedCode, $closingTag + 5); $highlightedCode = $tmp; } // remove breaks $highlightedCode = str_replace("\n", "", $highlightedCode); $highlightedCode = str_replace('<br />', "\n", $highlightedCode); // get tabs back $highlightedCode = str_replace(' ', "\t", $highlightedCode); // replace non breaking space with normal space, white-space is preserved by CSS $highlightedCode = str_replace(' ', " ", $highlightedCode); // convert colors to classes $highlightedCode = strtr($highlightedCode, self::$colorToClass); // replace double quotes by entity return Regex::compile('(?<!\\<span class=)"(?!\\>)')->replace($highlightedCode, '"'); }
/** * Returns true if update server requires license data instead of username/password. * * @return integer */ public final function requiresLicense() { return Regex::compile('^https?://update.woltlab.com/')->match($this->serverURL); }
/** * @see \wcf\form\IForm::validate() */ public function validate() { parent::validate(); // validate question if (!I18nHandler::getInstance()->validateValue('question')) { if (I18nHandler::getInstance()->isPlainValue('question')) { throw new UserInputException('question'); } else { throw new UserInputException('question', 'multilingual'); } } // validate answers if (!I18nHandler::getInstance()->validateValue('answers')) { if (I18nHandler::getInstance()->isPlainValue('answers')) { throw new UserInputException('answers'); } else { throw new UserInputException('answers', 'multilingual'); } } if (I18nHandler::getInstance()->isPlainValue('answers')) { $answers = explode("\n", StringUtil::unifyNewlines(I18nHandler::getInstance()->getValue('answers'))); foreach ($answers as $answer) { if (mb_substr($answer, 0, 1) == '~' && mb_substr($answer, -1, 1) == '~') { $regexLength = mb_strlen($answer) - 2; if (!$regexLength || !Regex::compile(mb_substr($answer, 1, $regexLength))->isValid()) { $this->invalidRegex = $answer; throw new UserInputException('answers', 'regexNotValid'); } } } } foreach (I18nHandler::getInstance()->getValues('answers') as $languageAnswers) { $answers = explode("\n", StringUtil::unifyNewlines($languageAnswers)); foreach ($answers as $answer) { if (mb_substr($answer, 0, 1) == '~' && mb_substr($answer, -1, 1) == '~') { $regexLength = mb_strlen($answer) - 2; if (!$regexLength || !Regex::compile(mb_substr($answer, 1, $regexLength))->isValid()) { $this->invalidRegex = $answer; throw new UserInputException('answers', 'regexNotValid'); } } } } }
/** * @see \wcf\form\IForm::validate() */ public function validate() { parent::validate(); // validate fields if (empty($this->questionTitle)) { throw new \wcf\system\exception\UserInputException('questionTitle'); } if (!\wcf\system\language\I18nHandler::getInstance()->validateValue('questionMessage', false, true)) { throw new \wcf\system\exception\UserInputException('questionMessage'); } $lines = explode("\n", \wcf\util\StringUtil::unifyNewlines($this->questionMessage)); foreach ($lines as $line) { if (!\wcf\system\Regex::compile($line)->isValid()) { throw new \wcf\system\exception\UserInputException('questionMessage', 'notValid'); } } // end foreach-loop }
/** * @see \wcf\system\bbcode\IBBCode::getParsedTag() */ public function getParsedTag(array $openingTag, $content, array $closingTag, BBCodeParser $parser) { // encode html $content = self::trim($content); // get attributes $this->mapAttributes($openingTag); // fetch highlighter-classname $className = '\\wcf\\system\\bbcode\\highlighter\\PlainHighlighter'; // no highlighting for strings over a certain size, to prevent DoS // this serves as a safety net in case one of the regular expressions // in a highlighter causes PCRE to exhaust resources, such as the stack if (strlen($content) < 16384) { if ($this->codeType) { $className = '\\wcf\\system\\bbcode\\highlighter\\' . StringUtil::firstCharToUpperCase(mb_strtolower($this->codeType)) . 'Highlighter'; switch (mb_substr($className, strlen('\\wcf\\system\\bbcode\\highlighter\\'))) { case 'ShellHighlighter': $className = '\\wcf\\system\\bbcode\\highlighter\\BashHighlighter'; break; case 'C++Highlighter': $className = '\\wcf\\system\\bbcode\\highlighter\\CHighlighter'; break; case 'JavascriptHighlighter': $className = '\\wcf\\system\\bbcode\\highlighter\\JsHighlighter'; break; case 'LatexHighlighter': $className = '\\wcf\\system\\bbcode\\highlighter\\TexHighlighter'; break; } } else { // try to guess highlighter if (mb_strpos($content, '<?php') !== false) { $className = '\\wcf\\system\\bbcode\\highlighter\\PhpHighlighter'; } else { if (mb_strpos($content, '<html') !== false) { $className = '\\wcf\\system\\bbcode\\highlighter\\HtmlHighlighter'; } else { if (mb_strpos($content, '<?xml') === 0) { $className = '\\wcf\\system\\bbcode\\highlighter\\XmlHighlighter'; } else { if (mb_strpos($content, 'SELECT') === 0 || mb_strpos($content, 'UPDATE') === 0 || mb_strpos($content, 'INSERT') === 0 || mb_strpos($content, 'DELETE') === 0) { $className = '\\wcf\\system\\bbcode\\highlighter\\SqlHighlighter'; } else { if (mb_strpos($content, 'import java.') !== false) { $className = '\\wcf\\system\\bbcode\\highlighter\\JavaHighlighter'; } else { if (mb_strpos($content, "---") !== false && mb_strpos($content, "\n+++") !== false) { $className = '\\wcf\\system\\bbcode\\highlighter\\DiffHighlighter'; } else { if (mb_strpos($content, "\n#include ") !== false) { $className = '\\wcf\\system\\bbcode\\highlighter\\CHighlighter'; } else { if (mb_strpos($content, '#!/usr/bin/perl') === 0) { $className = '\\wcf\\system\\bbcode\\highlighter\\PerlHighlighter'; } else { if (mb_strpos($content, 'def __init__(self') !== false) { $className = '\\wcf\\system\\bbcode\\highlighter\\PythonHighlighter'; } else { if (Regex::compile('^#!/bin/(ba|z)?sh')->match($content)) { $className = '\\wcf\\system\\bbcode\\highlighter\\BashHighlighter'; } else { if (mb_strpos($content, '\\documentclass') !== false) { $className = '\\wcf\\system\\bbcode\\highlighter\\TexHighlighter'; } else { if (Regex::compile('[-\\+\\.,\\[\\]\\>\\<]{9}')->match($content)) { // 9 times a brainfuck char in a row -> seems to be brainfuck $className = '\\wcf\\system\\bbcode\\highlighter\\BrainfuckHighlighter'; } } } } } } } } } } } } } } if (!class_exists($className)) { $className = '\\wcf\\system\\bbcode\\highlighter\\PlainHighlighter'; } if ($parser->getOutputType() == 'text/html') { $highlightedContent = self::fixMarkup(explode("\n", $className::getInstance()->highlight($content))); // show template WCF::getTPL()->assign(array('lineNumbers' => self::makeLineNumbers($content, $this->startLineNumber), 'startLineNumber' => $this->startLineNumber, 'content' => $highlightedContent, 'highlighter' => $className::getInstance(), 'filename' => $this->filename, 'lines' => substr_count($content, "\n") + 1)); return WCF::getTPL()->fetch('codeBBCodeTag'); } else { if ($parser->getOutputType() == 'text/simplified-html') { return WCF::getLanguage()->getDynamicVariable('wcf.bbcode.code.text', array('highlighterTitle' => $className::getInstance()->getTitle(), 'lines' => substr_count($content, "\n") + 1)); } } }
/** * Returns true if given hash looks like a valid bcrypt hash. * * @param string $hash * @return boolean */ public static function isBlowfish($hash) { return Regex::compile('^\\$2[afxy]\\$')->match($hash) ? true : false; }
/** * @see \wcf\form\IForm::validate() */ public function validate() { parent::validate(); // validate label if (!I18nHandler::getInstance()->validateValue('rankTitle')) { if (I18nHandler::getInstance()->isPlainValue('rankTitle')) { throw new UserInputException('rankTitle'); } else { throw new UserInputException('rankTitle', 'multilingual'); } } // validate group if (!$this->groupID) { throw new UserInputException('groupID'); } $userGroup = UserGroup::getGroupByID($this->groupID); if ($userGroup === null || $userGroup->groupType == UserGroup::GUESTS || $userGroup->groupType == UserGroup::EVERYONE) { throw new UserInputException('groupID', 'notValid'); } // css class name if (empty($this->cssClassName)) { throw new UserInputException('cssClassName', 'empty'); } else { if (!in_array($this->cssClassName, $this->availableCssClassNames)) { throw new UserInputException('cssClassName', 'notValid'); } else { if ($this->cssClassName == 'custom') { if (!empty($this->customCssClassName) && !Regex::compile('^-?[_a-zA-Z]+[_a-zA-Z0-9-]+$')->match($this->customCssClassName)) { throw new UserInputException('cssClassName', 'notValid'); } } } } // required gender if ($this->requiredGender < 0 || $this->requiredGender > 2) { $this->requiredGender = 0; } }
/** * Formats a message for search result output. * * @param string $text * @return string */ public function parse($text) { // remove nonessentials $text = Regex::compile('<!-- begin:parser_nonessential -->.*?<!-- end:parser_nonessential -->', Regex::DOT_ALL)->replace($text, ''); // remove html codes $text = StringUtil::stripHTML($text); // decode html $text = StringUtil::decodeHTML($text); // get abstract $text = $this->getMessageAbstract($text); // encode html $text = StringUtil::encodeHTML($text); // do highlighting return KeywordHighlighter::getInstance()->doHighlight($text); }
/** * @see \wcf\form\IForm::validate() */ public function validate() { parent::validate(); // validate group if (!$this->groupID) { throw new UserInputException('groupID'); } $groups = $this->labelGroupList->getObjects(); if (!isset($groups[$this->groupID])) { throw new UserInputException('groupID', 'notValid'); } // validate label if (!I18nHandler::getInstance()->validateValue('label')) { if (I18nHandler::getInstance()->isPlainValue('label')) { throw new UserInputException('label'); } else { throw new UserInputException('label', 'multilingual'); } } // validate class name if (empty($this->cssClassName)) { throw new UserInputException('cssClassName', 'empty'); } else { if (!in_array($this->cssClassName, $this->availableCssClassNames)) { throw new UserInputException('cssClassName', 'notValid'); } else { if ($this->cssClassName == 'custom') { if (!empty($this->customCssClassName) && !Regex::compile('^-?[_a-zA-Z]+[_a-zA-Z0-9-]+$')->match($this->customCssClassName)) { throw new UserInputException('cssClassName', 'notValid'); } } } } }
/** * Returns an array with the list of all available workers. * * @return array */ public function generateList() { $directory = DirectoryUtil::getInstance(WCF_DIR . 'lib/system/worker/'); $workerList = $directory->getFiles(SORT_ASC, new Regex('Worker\\.class\\.php$')); $table = array(array('Class', 'Description')); foreach ($workerList as $worker) { $class = 'wcf\\system\\worker\\' . basename($worker, '.class.php'); if (!class_exists($class) && !interface_exists($class)) { Log::info('Invalid worker file: ', $worker); continue; } $reflection = new \ReflectionClass($class); if (!$reflection->isInstantiable()) { continue; } if (!ClassUtil::isInstanceOf($class, 'wcf\\system\\worker\\IWorker')) { Log::info('Invalid worker file: ', $worker); continue; } $docComment = explode("\n", StringUtil::unifyNewlines($reflection->getDocComment())); foreach ($docComment as $commentLine) { if (Regex::compile('[a-z]', Regex::CASE_INSENSITIVE)->match($commentLine)) { $comment = Regex::compile('^[^a-z]+', Regex::CASE_INSENSITIVE)->replace($commentLine, ''); break; } } $table[] = array(basename($worker, '.class.php'), $comment); } return $table; }
/** * @see \wcf\form\IForm::validate() */ public function validate() { parent::validate(); if (empty($this->noticeName)) { throw new UserInputException('noticeName'); } if (!I18nHandler::getInstance()->validateValue('notice')) { if (I18nHandler::getInstance()->isPlainValue('notice')) { throw new UserInputException('notice'); } else { throw new UserInputException('notice', 'multilingual'); } } // validate class name if (empty($this->cssClassName)) { throw new UserInputException('cssClassName'); } else { if (!in_array($this->cssClassName, $this->availableCssClassNames)) { throw new UserInputException('cssClassName', 'notValid'); } else { if ($this->cssClassName == 'custom') { if (empty($this->cssClassName)) { throw new UserInputException('cssClassName'); } if (!Regex::compile('^-?[_a-zA-Z]+[_a-zA-Z0-9-]+$')->match($this->customCssClassName)) { throw new UserInputException('cssClassName', 'notValid'); } } } } foreach ($this->groupedConditionObjectTypes as $groupedObjectTypes) { foreach ($groupedObjectTypes as $objectTypes) { if (is_array($objectTypes)) { foreach ($objectTypes as $objectType) { $objectType->getProcessor()->validate(); } } else { $objectTypes->getProcessor()->validate(); } } } }
/** * @see \wcf\form\IForm::validate() */ public function validate() { parent::validate(); // tag name must not be empty if (empty($this->bbcodeTag)) { throw new UserInputException('bbcodeTag'); } // tag may only contain alphanumeric chars if (!Regex::compile('^[a-z0-9]+$', Regex::CASE_INSENSITIVE)->match($this->bbcodeTag)) { throw new UserInputException('bbcodeTag', 'notValid'); } // disallow the Pseudo-BBCodes all and none if ($this->bbcodeTag == 'all' || $this->bbcodeTag == 'none') { throw new UserInputException('bbcodeTag', 'notValid'); } // check whether the tag is in use $bbcode = BBCode::getBBCodeByTag($this->bbcodeTag); if (!isset($this->bbcode) && $bbcode->bbcodeID || isset($this->bbcode) && $bbcode->bbcodeID != $this->bbcode->bbcodeID) { throw new UserInputException('bbcodeTag', 'inUse'); } // handle empty case first if (empty($this->allowedChildren)) { throw new UserInputException('allowedChildren'); } // validate syntax of allowedChildren: Optional all|none^ followed by a comma-separated list of bbcodes if (!empty($this->allowedChildren) && !Regex::compile('^(?:(?:all|none)\\^)?(?:[a-zA-Z0-9]+,)*[a-zA-Z0-9]+$')->match($this->allowedChildren)) { throw new UserInputException('allowedChildren', 'notValid'); } // validate class if (!empty($this->className) && !class_exists($this->className)) { throw new UserInputException('className', 'notFound'); } // validate attributes foreach ($this->attributes as $attribute) { // Check whether the pattern is a valid regex if (!Regex::compile($attribute->validationPattern)->isValid()) { throw new UserInputException('attributeValidationPattern' . $attribute->attributeNo, 'notValid'); } } // button if ($this->showButton) { // validate label if (!I18nHandler::getInstance()->validateValue('buttonLabel')) { if (I18nHandler::getInstance()->isPlainValue('buttonLabel')) { throw new UserInputException('buttonLabel'); } else { throw new UserInputException('buttonLabel', 'multilingual'); } } // validate image path if (empty($this->wysiwygIcon)) { throw new UserInputException('wysiwygIcon'); } } else { $this->buttonLabel = ''; } }
/** * @see \wcf\form\IForm::save() */ public function save() { AbstractForm::save(); // get options $saveOptions = $this->optionHandler->save(); $registerVia3rdParty = false; $avatarURL = ''; if ($this->isExternalAuthentication) { switch (WCF::getSession()->getVar('__3rdPartyProvider')) { case 'github': // GitHub if (WCF::getSession()->getVar('__githubData')) { $githubData = WCF::getSession()->getVar('__githubData'); $this->additionalFields['authData'] = 'github:' . WCF::getSession()->getVar('__githubToken'); WCF::getSession()->unregister('__githubData'); WCF::getSession()->unregister('__githubToken'); if (WCF::getSession()->getVar('__email') && WCF::getSession()->getVar('__email') == $this->email) { $registerVia3rdParty = true; } if (isset($githubData['bio']) && User::getUserOptionID('aboutMe') !== null) { $saveOptions[User::getUserOptionID('aboutMe')] = $githubData['bio']; } if (isset($githubData['location']) && User::getUserOptionID('location') !== null) { $saveOptions[User::getUserOptionID('location')] = $githubData['location']; } } break; case 'twitter': // Twitter if (WCF::getSession()->getVar('__twitterData')) { $twitterData = WCF::getSession()->getVar('__twitterData'); $this->additionalFields['authData'] = 'twitter:' . $twitterData['user_id']; WCF::getSession()->unregister('__twitterData'); if (isset($twitterData['description']) && User::getUserOptionID('aboutMe') !== null) { $saveOptions[User::getUserOptionID('aboutMe')] = $twitterData['description']; } if (isset($twitterData['location']) && User::getUserOptionID('location') !== null) { $saveOptions[User::getUserOptionID('location')] = $twitterData['location']; } } break; case 'facebook': // Facebook if (WCF::getSession()->getVar('__facebookData')) { $facebookData = WCF::getSession()->getVar('__facebookData'); $this->additionalFields['authData'] = 'facebook:' . $facebookData['id']; WCF::getSession()->unregister('__facebookData'); if (isset($facebookData['email']) && $facebookData['email'] == $this->email) { $registerVia3rdParty = true; } if (isset($facebookData['gender']) && User::getUserOptionID('gender') !== null) { $saveOptions[User::getUserOptionID('gender')] = $facebookData['gender'] == 'male' ? UserProfile::GENDER_MALE : UserProfile::GENDER_FEMALE; } if (isset($facebookData['birthday']) && User::getUserOptionID('birthday') !== null) { list($month, $day, $year) = explode('/', $facebookData['birthday']); $saveOptions[User::getUserOptionID('birthday')] = $year . '-' . $month . '-' . $day; } if (isset($facebookData['bio']) && User::getUserOptionID('bio') !== null) { $saveOptions[User::getUserOptionID('aboutMe')] = $facebookData['bio']; } if (isset($facebookData['location']) && User::getUserOptionID('location') !== null) { $saveOptions[User::getUserOptionID('location')] = $facebookData['location']['name']; } if (isset($facebookData['website']) && User::getUserOptionID('website') !== null) { $urls = preg_split('/[\\s,;]/', $facebookData['website'], -1, PREG_SPLIT_NO_EMPTY); if (!empty($urls)) { if (!Regex::compile('^https?://')->match($urls[0])) { $urls[0] = 'http://' . $urls[0]; } $saveOptions[User::getUserOptionID('homepage')] = $urls[0]; } } // avatar if (isset($facebookData['picture']) && !$facebookData['picture']['data']['is_silhouette']) { $avatarURL = $facebookData['picture']['data']['url']; } } break; case 'google': // Google Plus if (WCF::getSession()->getVar('__googleData')) { $googleData = WCF::getSession()->getVar('__googleData'); $this->additionalFields['authData'] = 'google:' . $googleData['id']; WCF::getSession()->unregister('__googleData'); if (isset($googleData['emails'][0]['value']) && $googleData['emails'][0]['value'] == $this->email) { $registerVia3rdParty = true; } if (isset($googleData['gender']) && User::getUserOptionID('gender') !== null) { switch ($googleData['gender']) { case 'male': $saveOptions[User::getUserOptionID('gender')] = UserProfile::GENDER_MALE; break; case 'female': $saveOptions[User::getUserOptionID('gender')] = UserProfile::GENDER_FEMALE; break; } } if (isset($googleData['birthday']) && User::getUserOptionID('birthday') !== null) { $saveOptions[User::getUserOptionID('birthday')] = $googleData['birthday']; } if (isset($googleData['placesLived']) && User::getUserOptionID('location') !== null) { // save primary location $saveOptions[User::getUserOptionID('location')] = current(array_map(function ($element) { return $element['value']; }, array_filter($googleData['placesLived'], function ($element) { return isset($element['primary']) && $element['primary']; }))); } // avatar if (isset($googleData['image']['url'])) { $avatarURL = $googleData['image']['url']; } } break; } // create fake password $this->password = StringUtil::getRandomID(); } $this->additionalFields['languageID'] = $this->languageID; if (LOG_IP_ADDRESS) { $this->additionalFields['registrationIpAddress'] = WCF::getSession()->ipAddress; } // generate activation code $addDefaultGroups = true; if (REGISTER_ACTIVATION_METHOD == 1 && !$registerVia3rdParty || REGISTER_ACTIVATION_METHOD == 2) { $activationCode = UserRegistrationUtil::getActivationCode(); $this->additionalFields['activationCode'] = $activationCode; $addDefaultGroups = false; $this->groupIDs = UserGroup::getGroupIDsByType(array(UserGroup::EVERYONE, UserGroup::GUESTS)); } // check gravatar support if (MODULE_GRAVATAR && Gravatar::test($this->email)) { $this->additionalFields['enableGravatar'] = 1; } // create user $data = array('data' => array_merge($this->additionalFields, array('username' => $this->username, 'email' => $this->email, 'password' => $this->password)), 'groups' => $this->groupIDs, 'languageIDs' => $this->visibleLanguages, 'options' => $saveOptions, 'addDefaultGroups' => $addDefaultGroups); $this->objectAction = new UserAction(array(), 'create', $data); $result = $this->objectAction->executeAction(); $user = $result['returnValues']; $userEditor = new UserEditor($user); // update session WCF::getSession()->changeUser($user); // set avatar if provided if (!empty($avatarURL)) { $userAvatarAction = new UserAvatarAction(array(), 'fetchRemoteAvatar', array('url' => $avatarURL, 'userEditor' => $userEditor)); $userAvatarAction->executeAction(); } // activation management if (REGISTER_ACTIVATION_METHOD == 0) { $this->message = 'wcf.user.register.success'; } else { if (REGISTER_ACTIVATION_METHOD == 1) { // registering via 3rdParty leads to instant activation if ($registerVia3rdParty) { $this->message = 'wcf.user.register.success'; } else { $mail = new Mail(array($this->username => $this->email), WCF::getLanguage()->getDynamicVariable('wcf.user.register.needActivation.mail.subject'), WCF::getLanguage()->getDynamicVariable('wcf.user.register.needActivation.mail', array('user' => $user))); $mail->send(); $this->message = 'wcf.user.register.needActivation'; } } else { if (REGISTER_ACTIVATION_METHOD == 2) { $this->message = 'wcf.user.register.awaitActivation'; } } } // notify admin if (REGISTER_ADMIN_NOTIFICATION) { // get default language $language = LanguageFactory::getInstance()->getLanguage(LanguageFactory::getInstance()->getDefaultLanguageID()); // send mail $mail = new Mail(MAIL_ADMIN_ADDRESS, $language->getDynamicVariable('wcf.user.register.notification.mail.subject'), $language->getDynamicVariable('wcf.user.register.notification.mail', array('user' => $user))); $mail->setLanguage($language); $mail->send(); } if ($this->captchaObjectType) { $this->captchaObjectType->getProcessor()->reset(); } if (WCF::getSession()->getVar('noRegistrationCaptcha')) { WCF::getSession()->unregister('noRegistrationCaptcha'); } // login user UserAuthenticationFactory::getInstance()->getUserAuthentication()->storeAccessData($user, $this->username, $this->password); WCF::getSession()->unregister('registrationRandomFieldNames'); WCF::getSession()->unregister('registrationStartTime'); $this->saved(); // forward to index page HeaderUtil::delayedRedirect(LinkHandler::getInstance()->getLink(), WCF::getLanguage()->getDynamicVariable($this->message, array('user' => $user)), 15); exit; }
/** * @see \wcf\system\bbcode\IBBCode::getParsedTag() */ public function getParsedTag(array $openingTag, $content, array $closingTag, BBCodeParser $parser) { if ($parser->getOutputType() == 'text/html') { $parsedContent = Regex::compile('(?:\\s|<br />)*(\\[tr\\].*\\[/tr\\])(?:\\s|<br />)*', Regex::CASE_INSENSITIVE | Regex::DOT_ALL)->replace($content, '\\1'); // check syntax $regex = new Regex('\\[/?t[rd]\\]', Regex::CASE_INSENSITIVE); if ($regex->match($parsedContent, true)) { $matches = $regex->getMatches(); $openTags = array(); $openTDs = 0; $firstRowTDs = 0; // parse tags foreach ($matches[0] as $match) { switch ($match) { case '[td]': if (end($openTags) !== '[tr]') { return; } $openTags[] = $match; $openTDs++; break; case '[/td]': if (end($openTags) !== '[td]') { return; } array_pop($openTags); break; case '[tr]': if (!empty($openTags)) { return; } $openTags[] = $match; break; case '[/tr]': if (end($openTags) !== '[tr]') { return; } array_pop($openTags); // check that every row has got the same number of tds if ($firstRowTDs === 0) { $firstRowTDs = $openTDs; } if ($openTDs !== $firstRowTDs) { return; } $openTDs = 0; break; } } if (!empty($openTags)) { return; } } else { return ''; } // tr $parsedContent = Regex::compile('\\[tr\\](?:\\s|<br />)*', Regex::CASE_INSENSITIVE)->replace($parsedContent, '<tr>'); // td $parsedContent = str_ireplace('[td]', '<td>', $parsedContent); // /td $parsedContent = Regex::compile('\\[/td\\](?:\\s|<br />)*', Regex::CASE_INSENSITIVE)->replace($parsedContent, '</td>'); // /tr $parsedContent = Regex::compile('\\[/tr\\](?:\\s|<br />)*', Regex::CASE_INSENSITIVE)->replace($parsedContent, '</tr>'); return '<div class="container bbcodeTable"><table class="table responsiveTable"><tbody>' . $parsedContent . '</tbody></table></div>'; } else { if ($parser->getOutputType() == 'text/simplified-html') { // remove table tags $content = str_ireplace('[td]', '* ', $content); $content = str_ireplace('[/td]', ' ', $content); $content = str_ireplace('[tr]', '', $content); $content = str_ireplace('[/tr]', '', $content); return $content; } } }
/** * Assigns element values to template. Using request data once reading * initial database data is explicitly disallowed. * * @param boolean $useRequestData */ public function assignVariables($useRequestData = true) { $elementValues = array(); $elementValuesI18n = array(); foreach ($this->elementIDs as $elementID) { $value = ''; $i18nValues = array(); // use POST values instead of querying database if ($useRequestData) { if ($this->isPlainValue($elementID)) { $value = $this->getValue($elementID); } else { if ($this->hasI18nValues($elementID)) { $i18nValues = $this->i18nValues[$elementID]; // encoding the entries for javascript foreach ($i18nValues as $languageID => $value) { $i18nValues[$languageID] = StringUtil::encodeJS(StringUtil::unifyNewlines($value)); } } else { $i18nValues = array(); } } } else { $isI18n = Regex::compile('^' . $this->elementOptions[$elementID]['pattern'] . '$')->match($this->elementOptions[$elementID]['value']); if (!$isI18n) { // check if it's a regular language variable $isI18n = Regex::compile('^([a-zA-Z0-9-_]+\\.)+[a-zA-Z0-9-_]+$')->match($this->elementOptions[$elementID]['value']); } if ($isI18n) { // use i18n values from language items $sql = "SELECT\tlanguageID, languageItemValue\n\t\t\t\t\t\tFROM\twcf" . WCF_N . "_language_item\n\t\t\t\t\t\tWHERE\tlanguageItem = ?"; $statement = WCF::getDB()->prepareStatement($sql); $statement->execute(array($this->elementOptions[$elementID]['value'])); while ($row = $statement->fetchArray()) { $languageItemValue = StringUtil::unifyNewlines($row['languageItemValue']); $i18nValues[$row['languageID']] = StringUtil::encodeJS($languageItemValue); if ($row['languageID'] == LanguageFactory::getInstance()->getDefaultLanguageID()) { $value = $languageItemValue; } } // item appeared to be a language item but either is not or does not exist if (empty($i18nValues) && empty($value)) { $value = $this->elementOptions[$elementID]['value']; } } else { // use data provided by setOptions() $value = $this->elementOptions[$elementID]['value']; } } $elementValues[$elementID] = $value; $elementValuesI18n[$elementID] = $i18nValues; } WCF::getTPL()->assign(array('availableLanguages' => $this->availableLanguages, 'i18nPlainValues' => $elementValues, 'i18nValues' => $elementValuesI18n)); }
/** * Truncates a formatted message and keeps the HTML syntax intact. * * @param string $message string which shall be truncated * @param integer $maxLength string length after truncating * @return string truncated string */ public static function truncateFormattedMessage($message, $maxLength = 1000) { $message = Regex::compile('<!-- begin:parser_nonessential -->.*?<!-- end:parser_nonessential -->', Regex::DOT_ALL)->replace($message, ''); return StringUtil::truncateHTML($message, $maxLength); }