aboutsummaryrefslogtreecommitdiffstats
path: root/tests/bbcode/url_bbcode_test.php
blob: 83176abe4c271412deb0bf956fb05f8a9022d8be (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
<?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.
*
*/

require_once dirname(__FILE__) . '/../../phpBB/includes/functions.php';
require_once dirname(__FILE__) . '/../../phpBB/includes/functions_content.php';
require_once dirname(__FILE__) . '/../../phpBB/includes/bbcode.php';
require_once dirname(__FILE__) . '/../../phpBB/includes/message_parser.php';

class phpbb_url_bbcode_test extends phpbb_test_case
{
	public function url_bbcode_test_data()
	{
		return array(
			array(
				'url only',
				'[url]http://www.phpbb.com/community/[/url]',
				'[url:]http&#58;//www&#46;phpbb&#46;com/community/[/url:]'
			),
			array(
				'url with title',
				'[url=http://www.phpbb.com/community/]One line URL text[/url]',
				'[url=http&#58;//www&#46;phpbb&#46;com/community/:]One line URL text[/url:]'
			),
			array(
				'url with multiline title',
				"[url=http://www.phpbb.com/community/]Multiline\x0AURL\x0Atext[/url]",
				"[url=http&#58;//www&#46;phpbb&#46;com/community/:]Multiline\x0AURL\x0Atext[/url:]"
			),
			array(
				'unclosed url with multiline',
				"test [url] test \x0A test [url=http://www.phpbb.com/]test[/url] test",
				"test [url] test \x0A test [url=http&#58;//www&#46;phpbb&#46;com/:]test[/url:] test"
			),
			array(
				'unclosed url with multiline and title',
				"test [url=http://www.phpbb.com/]test \x0A [url]http://phpbb.com[/url] test",
				"test [url=http&#58;//www&#46;phpbb&#46;com/:]test \x0A [url]http://phpbb.com[/url:] test"
			),
		);
	}

	/**
	* @dataProvider url_bbcode_test_data
	*/
	public function test_url($description, $message, $expected)
	{
		global $user, $request;
		$user = new phpbb_mock_user;
		$request = new phpbb_mock_request;

		$bbcode = new bbcode_firstpass();
		$bbcode->message = $message;
		$bbcode->bbcode_init(false);
		$bbcode->parse_bbcode();
		$this->assertEquals($expected, $bbcode->message);
	}
}
>; # ISAAC, a 32-bit generator, should only be capable of generating numbers # between 0 and 2^32 - 1. We want _to_float to generate numbers possibly # including 0, but always less than 1.0. Dividing the integer produced # by irand() by this number should do that exactly. use constant DIVIDE_BY => 2**32; # How many bytes of seed to read. use constant SEED_SIZE => 16; # 128 bits. ################# # Windows Stuff # ################# # The type of cryptographic service provider we want to use. # This doesn't really matter for our purposes, so we just pick # PROV_RSA_FULL, which seems reasonable. For more info, see # http://msdn.microsoft.com/en-us/library/aa380244(v=VS.85).aspx use constant PROV_RSA_FULL => 1; # Flags for CryptGenRandom: # Don't ever display a UI to the user, just fail if one would be needed. use constant CRYPT_SILENT => 64; # Don't require existing public/private keypairs. use constant CRYPT_VERIFYCONTEXT => 0xF0000000; # For some reason, BOOLEAN doesn't work properly as a return type with # Win32::API. use constant RTLGENRANDOM_PROTO => <<END; INT SystemFunction036( PVOID RandomBuffer, ULONG RandomBufferLength ) END ################# # RNG Functions # ################# sub rand (;$) { my ($limit) = @_; my $int = irand(); return _to_float($int, $limit); } sub irand (;$) { my ($limit) = @_; Bugzilla::RNG::srand() if !defined $RNG; my $int = $RNG->irand(); if (defined $limit) { # We can't just use the mod operator because it will bias # our output. Search for "modulo bias" on the Internet for # details. This is slower than mod(), but does not have a bias, # as demonstrated by Math::Random::Secure's uniform.t test. return int(_to_float($int, $limit)); } return $int; } sub srand (;$) { my ($value) = @_; # Remove any RNG that might already have been made. $RNG = undef; my %args; if (defined $value) { $args{seed} = $value; } $RNG = _create_rng(\%args); } sub _to_float { my ($integer, $limit) = @_; $limit ||= 1; return ($integer / DIVIDE_BY) * $limit; } ########################## # Seed and PRNG Creation # ########################## sub _create_rng { my ($params) = @_; if (!defined $params->{seed}) { $params->{seed} = _get_seed(); } _check_seed($params->{seed}); my @seed_ints = unpack('L*', $params->{seed}); my $rng = Math::Random::ISAAC->new(@seed_ints); # It's faster to skip the frontend interface of Math::Random::ISAAC # and just use the backend directly. However, in case the internal # code of Math::Random::ISAAC changes at some point, we do make sure # that the {backend} element actually exists first. return $rng->{backend} ? $rng->{backend} : $rng; } sub _check_seed { my ($seed) = @_; if (length($seed) < 8) { warn "Your seed is less than 8 bytes (64 bits). It could be" . " easy to crack"; } # If it looks like we were seeded with a 32-bit integer, warn the # user that they are making a dangerous, easily-crackable mistake. elsif (length($seed) <= 10 and $seed =~ /^\d+$/) { warn "RNG seeded with a 32-bit integer, this is easy to crack"; } } sub _get_seed { return _windows_seed() if ON_WINDOWS; if (-r '/dev/urandom') { return _read_seed_from('/dev/urandom'); } return _read_seed_from('/dev/random'); } sub _read_seed_from { my ($from) = @_; open(my $fh, '<', $from) or die "$from: $!"; my $buffer; read($fh, $buffer, SEED_SIZE); if (length($buffer) < SEED_SIZE) { die "Could not read enough seed bytes from $from, got only " . length($buffer); } close $fh; return $buffer; } sub _windows_seed { my ($major, $minor) = (Win32::GetOSVersion())[1,2]; if ($major < 5) { die "Bugzilla does not support versions of Windows before" . " Windows 2000"; } # This means Windows 2000. if ($major == 5 and $minor == 0) { return _win2k_seed(); } my $rtlgenrand = Win32::API->new('advapi32', RTLGENRANDOM_PROTO); if (!defined $rtlgenrand) { die "Could not import RtlGenRand: $^E"; } my $buffer = chr(0) x SEED_SIZE; my $result = $rtlgenrand->Call($buffer, SEED_SIZE); if (!$result) { die "RtlGenRand failed: $^E"; } return $buffer; } sub _win2k_seed { my $crypt_acquire = Win32::API->new( "advapi32", 'CryptAcquireContext', 'PPPNN', 'I'); if (!defined $crypt_acquire) { die "Could not import CryptAcquireContext: $^E"; } my $crypt_release = Win32::API->new( "advapi32", 'CryptReleaseContext', 'NN', 'I'); if (!defined $crypt_release) { die "Could not import CryptReleaseContext: $^E"; } my $crypt_gen_random = Win32::API->new( "advapi32", 'CryptGenRandom', 'NNP', 'I'); if (!defined $crypt_gen_random) { die "Could not import CryptGenRandom: $^E"; } my $context = chr(0) x Win32::API::Type->sizeof('PULONG'); my $acquire_result = $crypt_acquire->Call( $context, 0, 0, PROV_RSA_FULL, CRYPT_SILENT | CRYPT_VERIFYCONTEXT); if (!defined $acquire_result) { die "CryptAcquireContext failed: $^E"; } my $pack_type = Win32::API::Type::packing('PULONG'); $context = unpack($pack_type, $context); my $buffer = chr(0) x SEED_SIZE; my $rand_result = $crypt_gen_random->Call($context, SEED_SIZE, $buffer); my $rand_error = $^E; # We don't check this if it fails, we don't care. $crypt_release->Call($context, 0); if (!defined $rand_result) { die "CryptGenRandom failed: $rand_error"; } return $buffer; } 1; =head1 B<Methods in need of POD> =over =item srand =item rand =item irand =back