diff options
| -rw-r--r-- | .appveyor.yml | 24 | ||||
| -rw-r--r-- | build/build.xml | 4 | ||||
| -rw-r--r-- | phpBB/develop/regex_idn.php | 2 | ||||
| -rw-r--r-- | phpBB/docs/CHANGELOG.html | 56 | ||||
| -rw-r--r-- | phpBB/includes/functions.php | 11 | ||||
| -rw-r--r-- | phpBB/includes/functions_convert.php | 2 | ||||
| -rw-r--r-- | phpBB/language/en/viewforum.php | 1 | ||||
| -rw-r--r-- | phpBB/phpbb/db/migration/data/v31x/v3112.php | 36 | ||||
| -rw-r--r-- | phpBB/phpbb/db/migration/data/v32x/v322.php | 37 | ||||
| -rw-r--r-- | phpBB/phpbb/install/module/update_filesystem/task/download_updated_files.php | 3 | ||||
| -rw-r--r-- | phpBB/phpbb/profilefields/type/type_url.php | 15 | ||||
| -rw-r--r-- | phpBB/phpbb/search/fulltext_postgres.php | 2 | ||||
| -rw-r--r-- | phpBB/styles/prosilver/template/viewforum_body.html | 4 | ||||
| -rw-r--r-- | tests/functions/make_clickable_test.php | 12 | ||||
| -rw-r--r-- | tests/profilefields/type_string_test.php | 15 | ||||
| -rw-r--r-- | tests/profilefields/type_url_test.php | 70 | ||||
| -rw-r--r-- | tests/test_framework/phpbb_functional_test_case.php | 7 | 
17 files changed, 276 insertions, 25 deletions
| diff --git a/.appveyor.yml b/.appveyor.yml index e536a561ff..a4fac799b2 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -15,10 +15,10 @@ environment:      php: 7.0    - db: mssql      db_version: sql2016 -    php: 7.0 -  - db: mssql -    db_version: sql2017 -    php: 7.1 +    php: 7.1.12 +#  - db: mssql +#    db_version: sql2017 +#    php: 7.1  #  - db: mariadb  #    php: 7.1  #  - db: mysqli @@ -40,10 +40,10 @@ before_test:    - ps: |        Set-Service wuauserv -StartupType Manual        cinst -y php --version ((choco search php --exact --all-versions -r | select-string -pattern $env:php | sort { [version]($_ -split '\|' | select -last 1) } -Descending | Select-Object -first 1) -replace '[php|]','') -      Get-ChildItem -Path "c:\tools\php$($env:php -replace '[.]','')" -Recurse | +      Get-ChildItem -Path "c:\tools\php$($env:php -replace '([0-9])[.]([0-9])[.]?([0-9]+)?','$1$2')" -Recurse |            Move-Item -destination "c:\tools\php"        cd c:\tools\php -      cat php.ini-production | %{$_ -replace "memory_limit = 128M","memory_limit = 1024M"} | Out-File -Encoding "Default" php.ini +      cat php.ini-development | %{$_ -replace "memory_limit = 128M","memory_limit = 1024M"} | Out-File -Encoding "Default" php.ini        Add-Content php.ini "`n date.timezone=UTC"        Add-Content php.ini "`n display_errors=On"        Add-Content php.ini "`n extension_dir=ext" @@ -64,10 +64,10 @@ before_test:        if ($env:db -eq "mssql") {          cd c:\tools\php\ext          $DLLVersion = "4.1.6.1" -        appveyor DownloadFile http://windows.php.net/downloads/pecl/releases/sqlsrv/$($:DLLVersion)/php_sqlsrv-$($DLLVersion)-$($env:php)-nts-vc14-x64.zip -        7z x -y php_sqlsrv-$($DLLVersion)-$($env:php)-nts-vc14-x64.zip > $null -        appveyor-retry appveyor DownloadFile http://windows.php.net/downloads/pecl/releases/pdo_sqlsrv/$($DLLVersion)/php_pdo_sqlsrv-$($DLLVersion)-$($env:php)-nts-vc14-x64.zip -        7z x -y php_pdo_sqlsrv-$($DLLVersion)-$($env:php)-nts-vc14-x64.zip > $null +        appveyor DownloadFile http://windows.php.net/downloads/pecl/releases/sqlsrv/$($:DLLVersion)/php_sqlsrv-$($DLLVersion)-$($env:php -replace '([0-9])[.]([0-9])[.]?([0-9]+)?','$1.$2')-nts-vc14-x64.zip +        7z x -y php_sqlsrv-$($DLLVersion)-$($env:php -replace '([0-9])[.]([0-9])[.]?([0-9]+)?','$1.$2')-nts-vc14-x64.zip > $null +        appveyor-retry appveyor DownloadFile http://windows.php.net/downloads/pecl/releases/pdo_sqlsrv/$($DLLVersion)/php_pdo_sqlsrv-$($DLLVersion)-$($env:php -replace '([0-9])[.]([0-9])[.]?([0-9]+)?','$1.$2')-nts-vc14-x64.zip +        7z x -y php_pdo_sqlsrv-$($DLLVersion)-$($env:php -replace '([0-9])[.]([0-9])[.]?([0-9]+)?','$1.$2')-nts-vc14-x64.zip > $null          Remove-Item c:\tools\php\* -include .zip          cd c:\tools\php          Add-Content php.ini "`nextension=php_sqlsrv.dll" @@ -114,6 +114,10 @@ before_test:        # Install PhantomJS        cinst -y phantomjs        Start-Process "phantomjs" "--webdriver=8910" | Out-Null +  - ps: | +      cd c:\projects\phpbb\phpBB +      (Get-Content c:\projects\phpbb\phpBB\web.config).replace("<configuration>", "<configuration>`n`t<system.web>`n`t`t<customErrors mode=`"Off`"/>`n`t</system.web>") | Set-Content c:\projects\phpbb\phpBB\web.config +      (Get-Content c:\projects\phpbb\phpBB\web.config).replace("`t</system.webServer>", "`t`t<httpErrors errorMode=`"Detailed`" />`n`t</system.webServer>") | Set-Content c:\projects\phpbb\phpBB\web.config    - cd c:\projects\phpbb\phpBB    - php ..\composer.phar install    - choco install -y urlrewrite diff --git a/build/build.xml b/build/build.xml index e748aabdb7..1491b95b48 100644 --- a/build/build.xml +++ b/build/build.xml @@ -3,8 +3,8 @@  <project name="phpBB" description="The phpBB forum software" default="all" basedir="../">  	<!-- a few settings for the build -->  	<property name="newversion" value="3.2.3-dev" /> -	<property name="prevversion" value="3.2.2-RC1" /> -	<property name="olderversions" value="3.0.14, 3.1.0, 3.1.1, 3.1.2, 3.1.3, 3.1.4, 3.1.5, 3.1.6, 3.1.7, 3.1.7-pl1, 3.1.8, 3.1.9, 3.1.10, 3.1.11, 3.2.0-a1, 3.2.0-a2, 3.2.0-b1, 3.2.0-b2, 3.2.0-RC1, 3.2.0-RC2, 3.2.0, 3.2.1" /> +	<property name="prevversion" value="3.2.2" /> +	<property name="olderversions" value="3.0.14, 3.1.0, 3.1.1, 3.1.2, 3.1.3, 3.1.4, 3.1.5, 3.1.6, 3.1.7, 3.1.7-pl1, 3.1.8, 3.1.9, 3.1.10, 3.1.11, 3.1.12, 3.2.0-a1, 3.2.0-a2, 3.2.0-b1, 3.2.0-b2, 3.2.0-RC1, 3.2.0-RC2, 3.2.0, 3.2.1" />  	<!-- no configuration should be needed beyond this point -->  	<property name="oldversions" value="${olderversions}, ${prevversion}" /> diff --git a/phpBB/develop/regex_idn.php b/phpBB/develop/regex_idn.php index d871695c50..30373f8de3 100644 --- a/phpBB/develop/regex_idn.php +++ b/phpBB/develop/regex_idn.php @@ -120,7 +120,7 @@ do  	$pct_encoded = "%[\dA-F]{2}";  	$unreserved = "$add_chars\pL0-9\-._~";  	$sub_delims = ($inline) ? '!$&\'(*+,;=' : '!$&\'()*+,;='; -	$scheme = ($inline) ? '[a-z][a-z\d+]*': '[a-z][a-z\d+\-.]*' ; // avoid automatic parsing of "word" in "last word.http://..." +	$scheme = ($inline) ? '[a-z][a-z\d+]*(?<!javascript)': '[a-z][a-z\d+\-.]*(?<!javascript)' ; // avoid automatic parsing of "word" in "last word.http://..."  	$pchar = "(?:[^$remove_chars]*[$unreserved$sub_delims:@|]+|$pct_encoded)"; // rfc: no "|"  	$reg_name = "(?:[^$remove_chars]*[$unreserved$sub_delims:@|]+|$pct_encoded)+"; // rfc: * instead of + and no "|" and no "@" and no ":" (included instead of userinfo) diff --git a/phpBB/docs/CHANGELOG.html b/phpBB/docs/CHANGELOG.html index aa982ddeca..13272e154c 100644 --- a/phpBB/docs/CHANGELOG.html +++ b/phpBB/docs/CHANGELOG.html @@ -58,6 +58,7 @@  		<li><a href="#v320a2">Changes since 3.2.0-a2</a></li>  		<li><a href="#v320a1">Changes since 3.2.0-a1</a></li>  		<li><a href="#v31x">Changes since 3.1.x</a></li> +		<li><a href="#v3111">Changes since 3.1.11</a></li>  		<li><a href="#v3110">Changes since 3.1.10</a></li>  		<li><a href="#v319">Changes since 3.1.9</a></li>  		<li><a href="#v318">Changes since 3.1.8</a></li> @@ -128,6 +129,10 @@  		<div class="content">  			<a name="v321"></a><h3>Changes since 3.2.1</h3> +			<h4>Security Issue</h4> +			<ul> +				<li>[SECURITY-211] - URLs with javascript scheme should not be made clickable</li> +			</ul>  			<h4>Bug</h4>  			<ul>  				<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-7845">PHPBB3-7845</a>] - Error on posting local image when script path is empty</li> @@ -190,6 +195,10 @@  				<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15464">PHPBB3-15464</a>] - Can't reparse [IMG] - in uppercase</li>  				<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15475">PHPBB3-15475</a>] - Restore Travis PR commit message validation</li>  				<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15478">PHPBB3-15478</a>] - core.js $loadingIndicator JavaScript errors</li> +				<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15489">PHPBB3-15489</a>] - Wrong footer text on forum of type "category"</li> +				<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15496">PHPBB3-15496</a>] - SQL Error in PostgreSQL Fulltext search when results displayed as topics</li> +				<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15497">PHPBB3-15497</a>] - Declaration of admin_activate_user::create_insert_array not compatible with base</li> +				<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15498">PHPBB3-15498</a>] - confirm_box() adds duplicate strings to URLs in extensions</li>  			</ul>  			<h4>Improvement</h4>  			<ul> @@ -850,6 +859,53 @@  				<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14265">PHPBB3-14265</a>] - Make all tables available in the container</li>  			</ul> +	<a name="v3111"></a><h3>Changes since 3.1.11</h3> + +	<h4>Security Issue</h4> +	<ul> +		<li>[SECURITY-211] - URLs with javascript scheme should not be made clickable</li> +	</ul> +	<h4>Bug</h4> +	<ul> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-9533">PHPBB3-9533</a>] - phpbb_own_realpath() doesn't always replicate realpath() behaviour</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-12835">PHPBB3-12835</a>] - Jump-box dropdown menu doesn't expand with according to line length in IE8</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13360">PHPBB3-13360</a>] - rename_too_long_indexes migration never deleted the old unique index</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13464">PHPBB3-13464</a>] - problem with drop down options and Arabic letters in chrome</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13574">PHPBB3-13574</a>] - Last post not showing in "Active topics" when Prosilver goes responsive</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15174">PHPBB3-15174</a>] - Unable to purge cache (ext & acp)</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15285">PHPBB3-15285</a>] - Travis tests are failing due to trusty changes</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15303">PHPBB3-15303</a>] - Typo in memcached driver</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15347">PHPBB3-15347</a>] - Password updater in cron generates invalid postgres SQL</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15367">PHPBB3-15367</a>] - Sphinx search backend doesn't escape special characters</li> +	</ul> +	<h4>Improvement</h4> +	<ul> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10122">PHPBB3-10122</a>] - [list=] - should support "none", along with CSS2 types</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11063">PHPBB3-11063</a>] - Change version check to SSL</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14820">PHPBB3-14820</a>] - Style Version Missing</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14919">PHPBB3-14919</a>] - Inconsistent use of globals vs class elements in acp_extensions</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14927">PHPBB3-14927</a>] - event core.user_add_modify_data</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14944">PHPBB3-14944</a>] - Add possibility to search for template loop indexes by key</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-14995">PHPBB3-14995</a>] - Add ACP template events acp_ext_list_*_name_after</li> +	</ul> +	<h4>New Feature</h4> +	<ul> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13344">PHPBB3-13344</a>] - Add new events for logging</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-15122">PHPBB3-15122</a>] - Support using memcached instead of memcache</li> +	</ul> +	<h4>Sub-task</h4> +	<ul> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11182">PHPBB3-11182</a>] - Ensure that template files use L_COLON instead of colons.</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-11676">PHPBB3-11676</a>] - generate_text_for_storage on includes/acp/acp_users.php</li> +	</ul> +	<h4>Task</h4> +	<ul> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10758">PHPBB3-10758</a>] - Improve Functional Test Code Coverage</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10791">PHPBB3-10791</a>] - Add a section for extensions to readme.html</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-10792">PHPBB3-10792</a>] - Add a section for 3.0 to 3.1 upgrades to install.html</li> +		<li>[<a href="http://tracker.phpbb.com/browse/PHPBB3-13874">PHPBB3-13874</a>] - Add master to sami API docs</li> +	</ul> +  	<a name="v3110"></a><h3>Changes since 3.1.10</h3>  	<h4>Bug</h4> diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php index e9b7d999b5..4aae84705b 100644 --- a/phpBB/includes/functions.php +++ b/phpBB/includes/functions.php @@ -2185,7 +2185,7 @@ function confirm_box($check, $title = '', $hidden = '', $html_body = 'confirm_bo  	// re-add sid / transform & to & for user->page (user->page is always using &)  	$use_page = ($u_action) ? $u_action : str_replace('&', '&', $user->page['page']); -	$u_action = reapply_sid($phpbb_path_helper->get_valid_page($use_page, $config['enable_mod_rewrite']), $phpbb_path_helper->is_router_used()); +	$u_action = reapply_sid($phpbb_path_helper->get_valid_page($use_page, $config['enable_mod_rewrite']));  	$u_action .= ((strpos($u_action, '?') === false) ? '?' : '&') . 'confirm_key=' . $confirm_key;  	$template->assign_vars(array( @@ -2780,12 +2780,17 @@ function get_preg_expression($mode)  		case 'url':  			// generated with regex_idn.php file in the develop folder -			return "[a-z][a-z\d+\-.]*:/{2}(?:(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'()*+,;=:@|]+|%[\dA-F]{2})+|[0-9.]+|\[[a-z0-9.]+:[a-z0-9.]+:[a-z0-9.:]+\])(?::\d*)?(?:/(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'()*+,;=:@|]+|%[\dA-F]{2})*)*(?:\?(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'()*+,;=:@/?|]+|%[\dA-F]{2})*)?(?:\#(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'()*+,;=:@/?|]+|%[\dA-F]{2})*)?"; +			return "[a-z][a-z\d+\-.]*(?<!javascript):/{2}(?:(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'()*+,;=:@|]+|%[\dA-F]{2})+|[0-9.]+|\[[a-z0-9.]+:[a-z0-9.]+:[a-z0-9.:]+\])(?::\d*)?(?:/(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'()*+,;=:@|]+|%[\dA-F]{2})*)*(?:\?(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'()*+,;=:@/?|]+|%[\dA-F]{2})*)?(?:\#(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'()*+,;=:@/?|]+|%[\dA-F]{2})*)?"; +		break; + +		case 'url_http': +			// generated with regex_idn.php file in the develop folder +			return "http[s]?:/{2}(?:(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'()*+,;=:@|]+|%[\dA-F]{2})+|[0-9.]+|\[[a-z0-9.]+:[a-z0-9.]+:[a-z0-9.:]+\])(?::\d*)?(?:/(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'()*+,;=:@|]+|%[\dA-F]{2})*)*(?:\?(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'()*+,;=:@/?|]+|%[\dA-F]{2})*)?(?:\#(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'()*+,;=:@/?|]+|%[\dA-F]{2})*)?";  		break;  		case 'url_inline':  			// generated with regex_idn.php file in the develop folder -			return "[a-z][a-z\d+]*:/{2}(?:(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'(*+,;=:@|]+|%[\dA-F]{2})+|[0-9.]+|\[[a-z0-9.]+:[a-z0-9.]+:[a-z0-9.:]+\])(?::\d*)?(?:/(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'(*+,;=:@|]+|%[\dA-F]{2})*)*(?:\?(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'(*+,;=:@/?|]+|%[\dA-F]{2})*)?(?:\#(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'(*+,;=:@/?|]+|%[\dA-F]{2})*)?"; +			return "[a-z][a-z\d+]*(?<!javascript):/{2}(?:(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'(*+,;=:@|]+|%[\dA-F]{2})+|[0-9.]+|\[[a-z0-9.]+:[a-z0-9.]+:[a-z0-9.:]+\])(?::\d*)?(?:/(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'(*+,;=:@|]+|%[\dA-F]{2})*)*(?:\?(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'(*+,;=:@/?|]+|%[\dA-F]{2})*)?(?:\#(?:[^\p{C}\p{Z}\p{S}\p{P}\p{Nl}\p{No}\p{Me}\x{1100}-\x{115F}\x{A960}-\x{A97C}\x{1160}-\x{11A7}\x{D7B0}-\x{D7C6}\x{20D0}-\x{20FF}\x{1D100}-\x{1D1FF}\x{1D200}-\x{1D24F}\x{0640}\x{07FA}\x{302E}\x{302F}\x{3031}-\x{3035}\x{303B}]*[\x{00B7}\x{0375}\x{05F3}\x{05F4}\x{30FB}\x{002D}\x{06FD}\x{06FE}\x{0F0B}\x{3007}\x{00DF}\x{03C2}\x{200C}\x{200D}\pL0-9\-._~!$&'(*+,;=:@/?|]+|%[\dA-F]{2})*)?";  		break;  		case 'www_url': diff --git a/phpBB/includes/functions_convert.php b/phpBB/includes/functions_convert.php index 4a8f664fe9..2cfbe9541d 100644 --- a/phpBB/includes/functions_convert.php +++ b/phpBB/includes/functions_convert.php @@ -249,7 +249,7 @@ function validate_website($url)  	{  		return '';  	} -	else if (!preg_match('#^[a-z0-9]+://#i', $url) && strlen($url) > 0) +	else if (!preg_match('#^http[s]?://#i', $url) && strlen($url) > 0)  	{  		return 'http://' . $url;  	} diff --git a/phpBB/language/en/viewforum.php b/phpBB/language/en/viewforum.php index cab205ddf9..e2a6e2a718 100644 --- a/phpBB/language/en/viewforum.php +++ b/phpBB/language/en/viewforum.php @@ -54,6 +54,7 @@ $lang = array_merge($lang, array(  	'NO_NEW_POSTS_HOT'		=> 'No new posts [ Popular ]',	// Not used anymore  	'NO_NEW_POSTS_LOCKED'	=> 'No new posts [ Locked ]',	// Not used anymore  	'NO_READ_ACCESS'		=> 'You do not have the required permissions to view or read topics within this forum.', +	'NO_FORUMS_IN_CATEGORY'	=> 'This category has no forums.',  	'NO_UNREAD_POSTS_HOT'		=> 'No unread posts [ Popular ]',  	'NO_UNREAD_POSTS_LOCKED'	=> 'No unread posts [ Locked ]', diff --git a/phpBB/phpbb/db/migration/data/v31x/v3112.php b/phpBB/phpbb/db/migration/data/v31x/v3112.php new file mode 100644 index 0000000000..0d75d35184 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v31x/v3112.php @@ -0,0 +1,36 @@ +<?php +/** +* +* This file is part of the phpBB Forum Software package. +* +* @copyright (c) phpBB Limited <https://www.phpbb.com> +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\db\migration\data\v31x; + +class v3112 extends \phpbb\db\migration\migration +{ +	public function effectively_installed() +	{ +		return phpbb_version_compare($this->config['version'], '3.1.12', '>='); +	} + +	static public function depends_on() +	{ +		return array( +			'\phpbb\db\migration\data\v31x\v3111', +		); +	} + +	public function update_data() +	{ +		return array( +			array('config.update', array('version', '3.1.12')), +		); +	} +} diff --git a/phpBB/phpbb/db/migration/data/v32x/v322.php b/phpBB/phpbb/db/migration/data/v32x/v322.php new file mode 100644 index 0000000000..7ecbbb3e79 --- /dev/null +++ b/phpBB/phpbb/db/migration/data/v32x/v322.php @@ -0,0 +1,37 @@ +<?php +/** +* +* This file is part of the phpBB Forum Software package. +* +* @copyright (c) phpBB Limited <https://www.phpbb.com> +* @license GNU General Public License, version 2 (GPL-2.0) +* +* For full copyright and license information, please see +* the docs/CREDITS.txt file. +* +*/ + +namespace phpbb\db\migration\data\v32x; + +class v322 extends \phpbb\db\migration\migration +{ +	public function effectively_installed() +	{ +		return phpbb_version_compare($this->config['version'], '3.2.2', '>='); +	} + +	static public function depends_on() +	{ +		return array( +			'\phpbb\db\migration\data\v31x\v3112', +			'\phpbb\db\migration\data\v32x\v322rc1', +		); +	} + +	public function update_data() +	{ +		return array( +			array('config.update', array('version', '3.2.2')), +		); +	} +} diff --git a/phpBB/phpbb/install/module/update_filesystem/task/download_updated_files.php b/phpBB/phpbb/install/module/update_filesystem/task/download_updated_files.php index 0b83e9a79d..4d7f0e0cdf 100644 --- a/phpBB/phpbb/install/module/update_filesystem/task/download_updated_files.php +++ b/phpBB/phpbb/install/module/update_filesystem/task/download_updated_files.php @@ -86,7 +86,8 @@ class download_updated_files extends task_base  		{  			$file_update_info = $this->installer_config->get('update_files', array()); -			if (count($file_update_info) > 0) +			// Display download box only if the archive won't be empty +			if (!empty($file_update_info) && !(isset($file_update_info['delete']) && count($file_update_info) == 1))  			{  				// Render download box  				$this->iohandler->add_download_link( diff --git a/phpBB/phpbb/profilefields/type/type_url.php b/phpBB/phpbb/profilefields/type/type_url.php index 375cf5b19a..37815b66a5 100644 --- a/phpBB/phpbb/profilefields/type/type_url.php +++ b/phpBB/phpbb/profilefields/type/type_url.php @@ -64,11 +64,24 @@ class type_url extends type_string  			return false;  		} -		if (!preg_match('#^' . get_preg_expression('url') . '$#iu', $field_value)) +		if (!preg_match('#^' . get_preg_expression('url_http') . '$#iu', $field_value))  		{  			return $this->user->lang('FIELD_INVALID_URL', $this->get_field_name($field_data['lang_name']));  		}  		return false;  	} + +	/** +	 * {@inheritDoc} +	 */ +	public function get_profile_value($field_value, $field_data) +	{ +		if (!preg_match('#^' . get_preg_expression('url_http') . '$#iu', $field_value)) +		{ +			return null; +		} + +		return parent::get_profile_value($field_value, $field_data); +	}  } diff --git a/phpBB/phpbb/search/fulltext_postgres.php b/phpBB/phpbb/search/fulltext_postgres.php index 4fe7e3b88d..6443342057 100644 --- a/phpBB/phpbb/search/fulltext_postgres.php +++ b/phpBB/phpbb/search/fulltext_postgres.php @@ -498,7 +498,7 @@ class fulltext_postgres extends \phpbb\search\base  		);  		extract($this->phpbb_dispatcher->trigger_event('core.search_postgres_keywords_main_query_before', compact($vars))); -		$sql_select			= ($type == 'posts') ? 'p.post_id' : 'DISTINCT t.topic_id'; +		$sql_select			= ($type == 'posts') ? 'p.post_id' : 'DISTINCT t.topic_id, ' . $sort_by_sql[$sort_key];  		$sql_from			= ($join_topic) ? TOPICS_TABLE . ' t, ' : '';  		$field				= ($type == 'posts') ? 'post_id' : 'topic_id'; diff --git a/phpBB/styles/prosilver/template/viewforum_body.html b/phpBB/styles/prosilver/template/viewforum_body.html index 994d75f244..b5e12cdde4 100644 --- a/phpBB/styles/prosilver/template/viewforum_body.html +++ b/phpBB/styles/prosilver/template/viewforum_body.html @@ -250,10 +250,10 @@  		<strong>{L_NO_TOPICS}</strong>  		</div>  	</div> -	<!-- ELSE IF not S_USER_CAN_POST --> +	<!-- ELSE IF not S_HAS_SUBFORUM -->  	<div class="panel">  		<div class="inner"> -			<strong>{L_NO_FORUMS}</strong> +			<strong>{L_NO_FORUMS_IN_CATEGORY}</strong>  		</div>  	</div>  	<!-- ENDIF --> diff --git a/tests/functions/make_clickable_test.php b/tests/functions/make_clickable_test.php index a351a6d527..a6af12b624 100644 --- a/tests/functions/make_clickable_test.php +++ b/tests/functions/make_clickable_test.php @@ -53,6 +53,14 @@ class phpbb_functions_make_clickable_test extends phpbb_test_case  				'<!-- l --><a class="postlink-local" href="http://testhost/viewtopic.php?t=1">viewtopic.php?t=1</a><!-- l -->'  			),  			array( +				'javascript://testhost/viewtopic.php?t=1', +				'javascript://testhost/viewtopic.php?t=1' +			), +			array( +				"java\nscri\npt://testhost/viewtopic.php?t=1", +				"java\nscri\n<!-- m --><a class=\"postlink\" href=\"pt://testhost/viewtopic.php?t=1\">pt://testhost/viewtopic.php?t=1</a><!-- m -->" +			), +			array(  				'email@domain.com',  				'<!-- e --><a href="mailto:email@domain.com">email@domain.com</a><!-- e -->'  			), @@ -90,6 +98,10 @@ class phpbb_functions_make_clickable_test extends phpbb_test_case  				'<!-- m --><a class="postlink" href="ftp://ftp.täst.de/">ftp://ftp.täst.de/</a><!-- m -->'  			),  			array( +				'javascript://täst.de/', +				'javascript://täst.de/' +			), +			array(  				'sip://bantu@täst.de',  				'<!-- m --><a class="postlink" href="sip://bantu@täst.de">sip://bantu@täst.de</a><!-- m -->'  			), diff --git a/tests/profilefields/type_string_test.php b/tests/profilefields/type_string_test.php index 7c7fa3f3e6..54bb406838 100644 --- a/tests/profilefields/type_string_test.php +++ b/tests/profilefields/type_string_test.php @@ -24,7 +24,7 @@ class phpbb_profilefield_type_string_test extends phpbb_test_case  	*/  	public function setUp()  	{ -		global $request, $user, $cache, $phpbb_root_path, $phpEx; +		global $config, $request, $user, $cache, $phpbb_root_path, $phpEx;  		$user = $this->getMock('\phpbb\user', array(), array(  			new \phpbb\language\language(new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx)), @@ -34,6 +34,7 @@ class phpbb_profilefield_type_string_test extends phpbb_test_case  		$user->expects($this->any())  			->method('lang')  			->will($this->returnCallback(array($this, 'return_callback_implode'))); +		$config = new \phpbb\config\config([]);  		$request = $this->getMock('\phpbb\request\request');  		$template = $this->getMock('\phpbb\template\template'); @@ -269,6 +270,18 @@ class phpbb_profilefield_type_string_test extends phpbb_test_case  				null,  				'Field should simply output null for empty vlaue',  			), +			array( +				'http://foobar.com', +				array('field_show_novalue' => false), +				'<!-- l --><a class="postlink-local" href="http://foobar.com">foobar.com</a><!-- l -->', +				'Field should output the given value and make it clickable', +			), +			array( +				'javascript://foobar.com', +				array('field_show_novalue' => true), +				'javascript://foobar.com', +				'Field should output the given value but not make it clickable', +			),  		);  	} diff --git a/tests/profilefields/type_url_test.php b/tests/profilefields/type_url_test.php index 1d90e2c34c..3bb5d52899 100644 --- a/tests/profilefields/type_url_test.php +++ b/tests/profilefields/type_url_test.php @@ -11,6 +11,10 @@  *  */ +require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php'; +require_once dirname(__FILE__) . '/../../phpBB/includes/functions_content.php'; +require_once dirname(__FILE__) . '/../../phpBB/includes/utf/utf_tools.php'; +  class phpbb_profilefield_type_url_test extends phpbb_test_case  {  	protected $cp; @@ -24,8 +28,10 @@ class phpbb_profilefield_type_url_test extends phpbb_test_case  	*/  	public function setUp()  	{ -		global $phpbb_root_path, $phpEx; +		global $config, $request, $user, $cache, $phpbb_root_path, $phpEx; +		$config = new \phpbb\config\config([]); +		$cache = new phpbb_mock_cache;  		$user = $this->getMock('\phpbb\user', array(), array(  			new \phpbb\language\language(new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx)),  			'\phpbb\datetime' @@ -92,6 +98,19 @@ class phpbb_profilefield_type_url_test extends phpbb_test_case  				'FIELD_INVALID_URL-field',  				'Field should reject invalid URL having multi value parameters',  			), +			// Not allowed schemes +			array( +				'ftp://example.com/', +				array(), +				'FIELD_INVALID_URL-field', +				'Field should reject invalid URL having multi value parameters', +			), +			array( +				'javascript://alert.com', +				array(), +				'FIELD_INVALID_URL-field', +				'Field should reject invalid URL having multi value parameters', +			),  			// IDN url type profilefields  			array( @@ -165,6 +184,55 @@ class phpbb_profilefield_type_url_test extends phpbb_test_case  		);  	} +	public function profile_value_data() +	{ +		return array( +			array( +				'http://foobar.com', +				array('field_show_novalue' => true), +				'<!-- l --><a class="postlink-local" href="http://foobar.com">foobar.com</a><!-- l -->', +				'Field should output the given value', +			), +			array( +				'http://foobar.com', +				array('field_show_novalue' => false), +				'<!-- l --><a class="postlink-local" href="http://foobar.com">foobar.com</a><!-- l -->', +				'Field should output the given value', +			), +			array( +				'test', +				array('field_show_novalue' => true), +				null, +				'Field should output nothing for empty value', +			), +			array( +				'test', +				array('field_show_novalue' => false), +				null, +				'Field should simply output null for empty value', +			), +			array( +				'javascript://foobar.com', +				array('field_show_novalue' => true), +				null, +				'Field should output nothing for empty value', +			), +		); +	} + + +	/** +	 * @dataProvider profile_value_data +	 */ +	public function test_get_profile_value($value, $field_options, $expected, $description) +	{ +		$field_options = array_merge($this->field_options, $field_options); + +		$result = $this->cp->get_profile_value($value, $field_options); + +		$this->assertSame($expected, $result, $description); +	} +  	/**  	* @dataProvider profile_value_raw_data  	*/ diff --git a/tests/test_framework/phpbb_functional_test_case.php b/tests/test_framework/phpbb_functional_test_case.php index 2be16c7198..e1daa4558a 100644 --- a/tests/test_framework/phpbb_functional_test_case.php +++ b/tests/test_framework/phpbb_functional_test_case.php @@ -911,10 +911,15 @@ class phpbb_functional_test_case extends phpbb_test_case  	* status code. This assertion tries to catch that.  	*  	* @param int $status_code	Expected status code -	* @return null +	* @return void  	*/  	static public function assert_response_status_code($status_code = 200)  	{ +		if ($status_code != self::$client->getResponse()->getStatus() && +			preg_match('/^5[0-9]{2}/', self::$client->getResponse()->getStatus())) +		{ +			self::fail("Encountered unexpected server error:\n" . self::$client->getResponse()->getContent()); +		}  		self::assertEquals($status_code, self::$client->getResponse()->getStatus(), 'HTTP status code does not match');  	} | 
