functions.php 49 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778
  1. <?php
  2. /**
  3. * @group functions.php
  4. */
  5. class Tests_Functions extends WP_UnitTestCase {
  6. function test_wp_parse_args_object() {
  7. $x = new MockClass;
  8. $x->_baba = 5;
  9. $x->yZ = 'baba'; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
  10. $x->a = array( 5, 111, 'x' );
  11. $this->assertSame(
  12. array(
  13. '_baba' => 5,
  14. 'yZ' => 'baba',
  15. 'a' => array( 5, 111, 'x' ),
  16. ),
  17. wp_parse_args( $x )
  18. );
  19. $y = new MockClass;
  20. $this->assertSame( array(), wp_parse_args( $y ) );
  21. }
  22. function test_wp_parse_args_array() {
  23. // Arrays.
  24. $a = array();
  25. $this->assertSame( array(), wp_parse_args( $a ) );
  26. $b = array(
  27. '_baba' => 5,
  28. 'yZ' => 'baba',
  29. 'a' => array( 5, 111, 'x' ),
  30. );
  31. $this->assertSame(
  32. array(
  33. '_baba' => 5,
  34. 'yZ' => 'baba',
  35. 'a' => array( 5, 111, 'x' ),
  36. ),
  37. wp_parse_args( $b )
  38. );
  39. }
  40. function test_wp_parse_args_defaults() {
  41. $x = new MockClass;
  42. $x->_baba = 5;
  43. $x->yZ = 'baba'; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
  44. $x->a = array( 5, 111, 'x' );
  45. $d = array( 'pu' => 'bu' );
  46. $this->assertSame(
  47. array(
  48. 'pu' => 'bu',
  49. '_baba' => 5,
  50. 'yZ' => 'baba',
  51. 'a' => array( 5, 111, 'x' ),
  52. ),
  53. wp_parse_args( $x, $d )
  54. );
  55. $e = array( '_baba' => 6 );
  56. $this->assertSame(
  57. array(
  58. '_baba' => 5,
  59. 'yZ' => 'baba',
  60. 'a' => array( 5, 111, 'x' ),
  61. ),
  62. wp_parse_args( $x, $e )
  63. );
  64. }
  65. function test_wp_parse_args_other() {
  66. $b = true;
  67. wp_parse_str( $b, $s );
  68. $this->assertSame( $s, wp_parse_args( $b ) );
  69. $q = 'x=5&_baba=dudu&';
  70. wp_parse_str( $q, $ss );
  71. $this->assertSame( $ss, wp_parse_args( $q ) );
  72. }
  73. /**
  74. * @ticket 30753
  75. */
  76. function test_wp_parse_args_boolean_strings() {
  77. $args = wp_parse_args( 'foo=false&bar=true' );
  78. $this->assertInternalType( 'string', $args['foo'] );
  79. $this->assertInternalType( 'string', $args['bar'] );
  80. }
  81. /**
  82. * @ticket 35972
  83. */
  84. function test_bool_from_yn() {
  85. $this->assertTrue( bool_from_yn( 'Y' ) );
  86. $this->assertTrue( bool_from_yn( 'y' ) );
  87. $this->assertFalse( bool_from_yn( 'n' ) );
  88. }
  89. function test_path_is_absolute() {
  90. $absolute_paths = array(
  91. '/',
  92. '/foo/',
  93. '/foo',
  94. '/FOO/bar',
  95. '/foo/bar/',
  96. '/foo/../bar/',
  97. '\\WINDOWS',
  98. 'C:\\',
  99. 'C:\\WINDOWS',
  100. '\\\\sambashare\\foo',
  101. );
  102. foreach ( $absolute_paths as $path ) {
  103. $this->assertTrue( path_is_absolute( $path ), "path_is_absolute('$path') should return true" );
  104. }
  105. }
  106. function test_path_is_not_absolute() {
  107. $relative_paths = array(
  108. '',
  109. '.',
  110. '..',
  111. '../foo',
  112. '../',
  113. '../foo.bar',
  114. 'foo/bar',
  115. 'foo',
  116. 'FOO',
  117. '..\\WINDOWS',
  118. );
  119. foreach ( $relative_paths as $path ) {
  120. $this->assertFalse( path_is_absolute( $path ), "path_is_absolute('$path') should return false" );
  121. }
  122. }
  123. /**
  124. * @ticket 33265
  125. * @ticket 35996
  126. *
  127. * @dataProvider data_wp_normalize_path
  128. */
  129. function test_wp_normalize_path( $path, $expected ) {
  130. $this->assertSame( $expected, wp_normalize_path( $path ) );
  131. }
  132. function data_wp_normalize_path() {
  133. return array(
  134. // Windows paths.
  135. array( 'C:\\www\\path\\', 'C:/www/path/' ),
  136. array( 'C:\\www\\\\path\\', 'C:/www/path/' ),
  137. array( 'c:/www/path', 'C:/www/path' ),
  138. array( 'c:\\www\\path\\', 'C:/www/path/' ), // Uppercase drive letter.
  139. array( 'c:\\\\www\\path\\', 'C:/www/path/' ),
  140. array( '\\\\Domain\\DFSRoots\\share\\path\\', '//Domain/DFSRoots/share/path/' ),
  141. array( '\\\\Server\\share\\path', '//Server/share/path' ),
  142. array( '\\\\Server\\share', '//Server/share' ),
  143. // Linux paths.
  144. array( '/www/path/', '/www/path/' ),
  145. array( '/www/path/////', '/www/path/' ),
  146. array( '/www/path', '/www/path' ),
  147. // PHP stream wrappers.
  148. array( 'php://input', 'php://input' ),
  149. array( 'http://example.com//path.ext', 'http://example.com/path.ext' ),
  150. array( 'file://c:\\www\\path\\', 'file://C:/www/path/' ),
  151. );
  152. }
  153. function test_wp_unique_filename() {
  154. $testdir = DIR_TESTDATA . '/images/';
  155. // Sanity check.
  156. $this->assertSame( 'abcdefg.png', wp_unique_filename( $testdir, 'abcdefg.png' ), 'Sanitiy check failed' );
  157. // Check number is appended for file already exists.
  158. $this->assertFileExists( $testdir . 'test-image.png', 'Test image does not exist' );
  159. $this->assertSame( 'test-image-1.png', wp_unique_filename( $testdir, 'test-image.png' ), 'Number not appended correctly' );
  160. $this->assertFileNotExists( $testdir . 'test-image-1.png' );
  161. // Check special chars.
  162. $this->assertSame( 'testtest-image.png', wp_unique_filename( $testdir, 'testtést-imagé.png' ), 'Filename with special chars failed' );
  163. // Check special chars with potential conflicting name.
  164. $this->assertSame( 'test-image-1.png', wp_unique_filename( $testdir, 'tést-imagé.png' ), 'Filename with special chars failed' );
  165. // Check with single quotes in name (somehow).
  166. $this->assertSame( 'abcdefgh.png', wp_unique_filename( $testdir, "abcdefg'h.png" ), 'File with quote failed' );
  167. // Check with double quotes in name (somehow).
  168. $this->assertSame( 'abcdefgh.png', wp_unique_filename( $testdir, 'abcdefg"h.png' ), 'File with quote failed' );
  169. // Test crazy name (useful for regression tests).
  170. $this->assertSame( '12af34567890@..^_qwerty-fghjkl-zx.png', wp_unique_filename( $testdir, '12%af34567890#~!@#$..%^&*()|_+qwerty fgh`jkl zx<>?:"{}[]="\'/?.png' ), 'Failed crazy file name' );
  171. // Test slashes in names.
  172. $this->assertSame( 'abcdefg.png', wp_unique_filename( $testdir, 'abcde\fg.png' ), 'Slash not removed' );
  173. $this->assertSame( 'abcdefg.png', wp_unique_filename( $testdir, 'abcde\\fg.png' ), 'Double slashed not removed' );
  174. $this->assertSame( 'abcdefg.png', wp_unique_filename( $testdir, 'abcde\\\fg.png' ), 'Tripple slashed not removed' );
  175. }
  176. /**
  177. * @ticket 42437
  178. */
  179. function test_unique_filename_with_dimension_like_filename() {
  180. $testdir = DIR_TESTDATA . '/images/';
  181. add_filter( 'upload_dir', array( $this, 'upload_dir_patch_basedir' ) );
  182. // Test collision with "dimension-like" original filename.
  183. $this->assertSame( 'one-blue-pixel-100x100-1.png', wp_unique_filename( $testdir, 'one-blue-pixel-100x100.png' ) );
  184. // Test collision with existing sub-size filename.
  185. // Existing files: one-blue-pixel-100x100.png, one-blue-pixel-1-100x100.png.
  186. $this->assertSame( 'one-blue-pixel-2.png', wp_unique_filename( $testdir, 'one-blue-pixel.png' ) );
  187. // Same as above with upper case extension.
  188. $this->assertSame( 'one-blue-pixel-2.png', wp_unique_filename( $testdir, 'one-blue-pixel.PNG' ) );
  189. remove_filter( 'upload_dir', array( $this, 'upload_dir_patch_basedir' ) );
  190. }
  191. // Callback to patch "basedir" when used in `wp_unique_filename()`.
  192. function upload_dir_patch_basedir( $upload_dir ) {
  193. $upload_dir['basedir'] = DIR_TESTDATA . '/images/';
  194. return $upload_dir;
  195. }
  196. /**
  197. * @dataProvider data_is_not_serialized
  198. */
  199. function test_maybe_serialize( $value ) {
  200. if ( is_array( $value ) || is_object( $value ) ) {
  201. $expected = serialize( $value );
  202. } else {
  203. $expected = $value;
  204. }
  205. $this->assertSame( $expected, maybe_serialize( $value ) );
  206. }
  207. /**
  208. * @dataProvider data_is_serialized
  209. */
  210. function test_maybe_serialize_with_double_serialization( $value ) {
  211. $expected = serialize( $value );
  212. $this->assertSame( $expected, maybe_serialize( $value ) );
  213. }
  214. /**
  215. * @dataProvider data_is_serialized
  216. * @dataProvider data_is_not_serialized
  217. */
  218. function test_maybe_unserialize( $value, $is_serialized ) {
  219. if ( $is_serialized ) {
  220. $expected = unserialize( trim( $value ) );
  221. } else {
  222. $expected = $value;
  223. }
  224. if ( is_object( $expected ) ) {
  225. $this->assertEquals( $expected, maybe_unserialize( $value ) );
  226. } else {
  227. $this->assertSame( $expected, maybe_unserialize( $value ) );
  228. }
  229. }
  230. /**
  231. * @dataProvider data_is_serialized
  232. * @dataProvider data_is_not_serialized
  233. */
  234. function test_is_serialized( $value, $expected ) {
  235. $this->assertSame( $expected, is_serialized( $value ) );
  236. }
  237. /**
  238. * @dataProvider data_serialize_deserialize_objects
  239. */
  240. function test_deserialize_request_utility_filtered_iterator_objects( $value ) {
  241. $serialized = maybe_serialize( $value );
  242. if ( get_class( $value ) === 'Requests_Utility_FilteredIterator' ) {
  243. $new_value = unserialize( $serialized );
  244. $property = ( new ReflectionClass( 'Requests_Utility_FilteredIterator' ) )->getProperty( 'callback' );
  245. $property->setAccessible( true );
  246. $callback_value = $property->getValue( $new_value );
  247. $this->assertSame( null, $callback_value );
  248. } else {
  249. $this->assertSame( $value->count(), unserialize( $serialized )->count() );
  250. }
  251. }
  252. function data_serialize_deserialize_objects() {
  253. return array(
  254. array( new Requests_Utility_FilteredIterator( array( 1 ), 'md5' ) ),
  255. array( new Requests_Utility_FilteredIterator( array( 1, 2 ), 'sha1' ) ),
  256. array( new ArrayIterator( array( 1, 2, 3 ) ) ),
  257. );
  258. }
  259. function data_is_serialized() {
  260. return array(
  261. array( serialize( null ), true ),
  262. array( serialize( true ), true ),
  263. array( serialize( false ), true ),
  264. array( serialize( -25 ), true ),
  265. array( serialize( 25 ), true ),
  266. array( serialize( 1.1 ), true ),
  267. array( serialize( 'this string will be serialized' ), true ),
  268. array( serialize( "a\nb" ), true ),
  269. array( serialize( array() ), true ),
  270. array( serialize( array( 1, 1, 2, 3, 5, 8, 13 ) ), true ),
  271. array(
  272. serialize(
  273. (object) array(
  274. 'test' => true,
  275. '3',
  276. 4,
  277. )
  278. ),
  279. true,
  280. ),
  281. array( ' s:25:"this string is serialized"; ', true ),
  282. );
  283. }
  284. function data_is_not_serialized() {
  285. return array(
  286. array( null, false ),
  287. array( true, false ),
  288. array( false, false ),
  289. array( -25, false ),
  290. array( 25, false ),
  291. array( 1.1, false ),
  292. array( 'this string will be serialized', false ),
  293. array( "a\nb", false ),
  294. array( array(), false ),
  295. array( array( 1, 1, 2, 3, 5, 8, 13 ), false ),
  296. array(
  297. (object) array(
  298. 'test' => true,
  299. '3',
  300. 4,
  301. ),
  302. false,
  303. ),
  304. array( 'a string', false ),
  305. array( 'garbage:a:0:garbage;', false ),
  306. array( 's:4:test;', false ),
  307. );
  308. }
  309. /**
  310. * @ticket 46570
  311. * @dataProvider data_is_serialized_should_return_true_for_large_floats
  312. */
  313. function test_is_serialized_should_return_true_for_large_floats( $value ) {
  314. $this->assertTrue( is_serialized( $value ) );
  315. }
  316. function data_is_serialized_should_return_true_for_large_floats() {
  317. return array(
  318. array( serialize( 1.7976931348623157E+308 ) ),
  319. array( serialize( array( 1.7976931348623157E+308, 1.23e50 ) ) ),
  320. );
  321. }
  322. /**
  323. * @ticket 17375
  324. */
  325. function test_no_new_serializable_types() {
  326. $this->assertFalse( is_serialized( 'C:16:"Serialized_Class":6:{a:0:{}}' ) );
  327. }
  328. /**
  329. * @group add_query_arg
  330. */
  331. function test_add_query_arg() {
  332. $old_req_uri = $_SERVER['REQUEST_URI'];
  333. $urls = array(
  334. '/',
  335. '/2012/07/30/',
  336. 'edit.php',
  337. admin_url( 'edit.php' ),
  338. admin_url( 'edit.php', 'https' ),
  339. );
  340. $frag_urls = array(
  341. '/#frag',
  342. '/2012/07/30/#frag',
  343. 'edit.php#frag',
  344. admin_url( 'edit.php#frag' ),
  345. admin_url( 'edit.php#frag', 'https' ),
  346. );
  347. foreach ( $urls as $url ) {
  348. $_SERVER['REQUEST_URI'] = 'nothing';
  349. $this->assertSame( "$url?foo=1", add_query_arg( 'foo', '1', $url ) );
  350. $this->assertSame( "$url?foo=1", add_query_arg( array( 'foo' => '1' ), $url ) );
  351. $this->assertSame(
  352. "$url?foo=2",
  353. add_query_arg(
  354. array(
  355. 'foo' => '1',
  356. 'foo' => '2',
  357. ),
  358. $url
  359. )
  360. );
  361. $this->assertSame(
  362. "$url?foo=1&bar=2",
  363. add_query_arg(
  364. array(
  365. 'foo' => '1',
  366. 'bar' => '2',
  367. ),
  368. $url
  369. )
  370. );
  371. $_SERVER['REQUEST_URI'] = $url;
  372. $this->assertSame( "$url?foo=1", add_query_arg( 'foo', '1' ) );
  373. $this->assertSame( "$url?foo=1", add_query_arg( array( 'foo' => '1' ) ) );
  374. $this->assertSame(
  375. "$url?foo=2",
  376. add_query_arg(
  377. array(
  378. 'foo' => '1',
  379. 'foo' => '2',
  380. )
  381. )
  382. );
  383. $this->assertSame(
  384. "$url?foo=1&bar=2",
  385. add_query_arg(
  386. array(
  387. 'foo' => '1',
  388. 'bar' => '2',
  389. )
  390. )
  391. );
  392. }
  393. foreach ( $frag_urls as $frag_url ) {
  394. $_SERVER['REQUEST_URI'] = 'nothing';
  395. $url = str_replace( '#frag', '', $frag_url );
  396. $this->assertSame( "$url?foo=1#frag", add_query_arg( 'foo', '1', $frag_url ) );
  397. $this->assertSame( "$url?foo=1#frag", add_query_arg( array( 'foo' => '1' ), $frag_url ) );
  398. $this->assertSame(
  399. "$url?foo=2#frag",
  400. add_query_arg(
  401. array(
  402. 'foo' => '1',
  403. 'foo' => '2',
  404. ),
  405. $frag_url
  406. )
  407. );
  408. $this->assertSame(
  409. "$url?foo=1&bar=2#frag",
  410. add_query_arg(
  411. array(
  412. 'foo' => '1',
  413. 'bar' => '2',
  414. ),
  415. $frag_url
  416. )
  417. );
  418. $_SERVER['REQUEST_URI'] = $frag_url;
  419. $this->assertSame( "$url?foo=1#frag", add_query_arg( 'foo', '1' ) );
  420. $this->assertSame( "$url?foo=1#frag", add_query_arg( array( 'foo' => '1' ) ) );
  421. $this->assertSame(
  422. "$url?foo=2#frag",
  423. add_query_arg(
  424. array(
  425. 'foo' => '1',
  426. 'foo' => '2',
  427. )
  428. )
  429. );
  430. $this->assertSame(
  431. "$url?foo=1&bar=2#frag",
  432. add_query_arg(
  433. array(
  434. 'foo' => '1',
  435. 'bar' => '2',
  436. )
  437. )
  438. );
  439. }
  440. $qs_urls = array(
  441. 'baz=1', // #WP4903
  442. '/?baz',
  443. '/2012/07/30/?baz',
  444. 'edit.php?baz',
  445. admin_url( 'edit.php?baz' ),
  446. admin_url( 'edit.php?baz', 'https' ),
  447. admin_url( 'edit.php?baz&za=1' ),
  448. admin_url( 'edit.php?baz=1&za=1' ),
  449. admin_url( 'edit.php?baz=0&za=0' ),
  450. );
  451. foreach ( $qs_urls as $url ) {
  452. $_SERVER['REQUEST_URI'] = 'nothing';
  453. $this->assertSame( "$url&foo=1", add_query_arg( 'foo', '1', $url ) );
  454. $this->assertSame( "$url&foo=1", add_query_arg( array( 'foo' => '1' ), $url ) );
  455. $this->assertSame(
  456. "$url&foo=2",
  457. add_query_arg(
  458. array(
  459. 'foo' => '1',
  460. 'foo' => '2',
  461. ),
  462. $url
  463. )
  464. );
  465. $this->assertSame(
  466. "$url&foo=1&bar=2",
  467. add_query_arg(
  468. array(
  469. 'foo' => '1',
  470. 'bar' => '2',
  471. ),
  472. $url
  473. )
  474. );
  475. $_SERVER['REQUEST_URI'] = $url;
  476. $this->assertSame( "$url&foo=1", add_query_arg( 'foo', '1' ) );
  477. $this->assertSame( "$url&foo=1", add_query_arg( array( 'foo' => '1' ) ) );
  478. $this->assertSame(
  479. "$url&foo=2",
  480. add_query_arg(
  481. array(
  482. 'foo' => '1',
  483. 'foo' => '2',
  484. )
  485. )
  486. );
  487. $this->assertSame(
  488. "$url&foo=1&bar=2",
  489. add_query_arg(
  490. array(
  491. 'foo' => '1',
  492. 'bar' => '2',
  493. )
  494. )
  495. );
  496. }
  497. $_SERVER['REQUEST_URI'] = $old_req_uri;
  498. }
  499. /**
  500. * @ticket 31306
  501. */
  502. function test_add_query_arg_numeric_keys() {
  503. $url = add_query_arg( array( 'foo' => 'bar' ), '1=1' );
  504. $this->assertSame( '1=1&foo=bar', $url );
  505. $url = add_query_arg(
  506. array(
  507. 'foo' => 'bar',
  508. '1' => '2',
  509. ),
  510. '1=1'
  511. );
  512. $this->assertSame( '1=2&foo=bar', $url );
  513. $url = add_query_arg( array( '1' => '2' ), 'foo=bar' );
  514. $this->assertSame( 'foo=bar&1=2', $url );
  515. }
  516. /**
  517. * @ticket 21594
  518. */
  519. function test_get_allowed_mime_types() {
  520. $mimes = get_allowed_mime_types();
  521. $this->assertInternalType( 'array', $mimes );
  522. $this->assertNotEmpty( $mimes );
  523. add_filter( 'upload_mimes', '__return_empty_array' );
  524. $mimes = get_allowed_mime_types();
  525. $this->assertInternalType( 'array', $mimes );
  526. $this->assertEmpty( $mimes );
  527. remove_filter( 'upload_mimes', '__return_empty_array' );
  528. $mimes = get_allowed_mime_types();
  529. $this->assertInternalType( 'array', $mimes );
  530. $this->assertNotEmpty( $mimes );
  531. }
  532. /**
  533. * @ticket 21594
  534. */
  535. function test_wp_get_mime_types() {
  536. $mimes = wp_get_mime_types();
  537. $this->assertInternalType( 'array', $mimes );
  538. $this->assertNotEmpty( $mimes );
  539. add_filter( 'mime_types', '__return_empty_array' );
  540. $mimes = wp_get_mime_types();
  541. $this->assertInternalType( 'array', $mimes );
  542. $this->assertEmpty( $mimes );
  543. remove_filter( 'mime_types', '__return_empty_array' );
  544. $mimes = wp_get_mime_types();
  545. $this->assertInternalType( 'array', $mimes );
  546. $this->assertNotEmpty( $mimes );
  547. // 'upload_mimes' should not affect wp_get_mime_types().
  548. add_filter( 'upload_mimes', '__return_empty_array' );
  549. $mimes = wp_get_mime_types();
  550. $this->assertInternalType( 'array', $mimes );
  551. $this->assertNotEmpty( $mimes );
  552. remove_filter( 'upload_mimes', '__return_empty_array' );
  553. $mimes2 = wp_get_mime_types();
  554. $this->assertInternalType( 'array', $mimes2 );
  555. $this->assertNotEmpty( $mimes2 );
  556. $this->assertSame( $mimes2, $mimes );
  557. }
  558. /**
  559. * @ticket 23688
  560. */
  561. function test_canonical_charset() {
  562. $orig_blog_charset = get_option( 'blog_charset' );
  563. update_option( 'blog_charset', 'utf8' );
  564. $this->assertSame( 'UTF-8', get_option( 'blog_charset' ) );
  565. update_option( 'blog_charset', 'utf-8' );
  566. $this->assertSame( 'UTF-8', get_option( 'blog_charset' ) );
  567. update_option( 'blog_charset', 'UTF8' );
  568. $this->assertSame( 'UTF-8', get_option( 'blog_charset' ) );
  569. update_option( 'blog_charset', 'UTF-8' );
  570. $this->assertSame( 'UTF-8', get_option( 'blog_charset' ) );
  571. update_option( 'blog_charset', 'ISO-8859-1' );
  572. $this->assertSame( 'ISO-8859-1', get_option( 'blog_charset' ) );
  573. update_option( 'blog_charset', 'ISO8859-1' );
  574. $this->assertSame( 'ISO-8859-1', get_option( 'blog_charset' ) );
  575. update_option( 'blog_charset', 'iso8859-1' );
  576. $this->assertSame( 'ISO-8859-1', get_option( 'blog_charset' ) );
  577. update_option( 'blog_charset', 'iso-8859-1' );
  578. $this->assertSame( 'ISO-8859-1', get_option( 'blog_charset' ) );
  579. // Arbitrary strings are passed through.
  580. update_option( 'blog_charset', 'foobarbaz' );
  581. $this->assertSame( 'foobarbaz', get_option( 'blog_charset' ) );
  582. update_option( 'blog_charset', $orig_blog_charset );
  583. }
  584. /**
  585. * @ticket 43977
  586. * @dataProvider data_wp_parse_list
  587. */
  588. function test_wp_parse_list( $expected, $actual ) {
  589. $this->assertSame( $expected, array_values( wp_parse_list( $actual ) ) );
  590. }
  591. function data_wp_parse_list() {
  592. return array(
  593. array( array( '1', '2', '3', '4' ), '1,2,3,4' ),
  594. array( array( 'apple', 'banana', 'carrot', 'dog' ), 'apple,banana,carrot,dog' ),
  595. array( array( '1', '2', 'apple', 'banana' ), '1,2,apple,banana' ),
  596. array( array( '1', '2', 'apple', 'banana' ), '1, 2,apple,banana' ),
  597. array( array( '1', '2', 'apple', 'banana' ), '1,2,apple,,banana' ),
  598. array( array( '1', '2', 'apple', 'banana' ), ',1,2,apple,banana' ),
  599. array( array( '1', '2', 'apple', 'banana' ), '1,2,apple,banana,' ),
  600. array( array( '1', '2', 'apple', 'banana' ), '1,2 ,apple,banana' ),
  601. array( array(), '' ),
  602. array( array(), ',' ),
  603. array( array(), ',,' ),
  604. );
  605. }
  606. /**
  607. * @dataProvider data_wp_parse_id_list
  608. */
  609. function test_wp_parse_id_list( $expected, $actual ) {
  610. $this->assertSame( $expected, array_values( wp_parse_id_list( $actual ) ) );
  611. }
  612. function data_wp_parse_id_list() {
  613. return array(
  614. array( array( 1, 2, 3, 4 ), '1,2,3,4' ),
  615. array( array( 1, 2, 3, 4 ), '1, 2,,3,4' ),
  616. array( array( 1, 2, 3, 4 ), '1,2,2,3,4' ),
  617. array( array( 1, 2, 3, 4 ), array( '1', '2', '3', '4', '3' ) ),
  618. array( array( 1, 2, 3, 4 ), array( 1, '2', 3, '4' ) ),
  619. array( array( 1, 2, 3, 4 ), '-1,2,-3,4' ),
  620. array( array( 1, 2, 3, 4 ), array( -1, 2, '-3', '4' ) ),
  621. );
  622. }
  623. /**
  624. * @dataProvider data_wp_parse_slug_list
  625. */
  626. function test_wp_parse_slug_list( $expected, $actual ) {
  627. $this->assertSame( $expected, array_values( wp_parse_slug_list( $actual ) ) );
  628. }
  629. function data_wp_parse_slug_list() {
  630. return array(
  631. array( array( 'apple', 'banana', 'carrot', 'dog' ), 'apple,banana,carrot,dog' ),
  632. array( array( 'apple', 'banana', 'carrot', 'dog' ), 'apple, banana,,carrot,dog' ),
  633. array( array( 'apple', 'banana', 'carrot', 'dog' ), 'apple banana carrot dog' ),
  634. array( array( 'apple', 'banana-carrot', 'd-o-g' ), array( 'apple ', 'banana carrot', 'd o g' ) ),
  635. );
  636. }
  637. /**
  638. * @dataProvider data_device_can_upload
  639. */
  640. function test_device_can_upload( $user_agent, $expected ) {
  641. $_SERVER['HTTP_USER_AGENT'] = $user_agent;
  642. $actual = _device_can_upload();
  643. unset( $_SERVER['HTTP_USER_AGENT'] );
  644. $this->assertSame( $expected, $actual );
  645. }
  646. function data_device_can_upload() {
  647. return array(
  648. // iPhone iOS 5.0.1, Safari 5.1.
  649. array(
  650. 'Mozilla/5.0 (iPhone; CPU iPhone OS 5_0_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Mobile/9A406)',
  651. false,
  652. ),
  653. // iPad iOS 3.2, Safari 4.0.4.
  654. array(
  655. 'Mozilla/5.0 (iPad; U; CPU OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B334b Safari/531.21.10',
  656. false,
  657. ),
  658. // iPod iOS 4.3.3, Safari 5.0.2.
  659. array(
  660. 'Mozilla/5.0 (iPod; U; CPU iPhone OS 4_3_3 like Mac OS X; ja-jp) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8J2 Safari/6533.18.5',
  661. false,
  662. ),
  663. // iPhone iOS 6.0.0, Safari 6.0.
  664. array(
  665. 'Mozilla/5.0 (iPhone; CPU iPhone OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A5376e Safari/8536.25',
  666. true,
  667. ),
  668. // iPad iOS 6.0.0, Safari 6.0.
  669. array(
  670. 'Mozilla/5.0 (iPad; CPU OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A5376e Safari/8536.25',
  671. true,
  672. ),
  673. // Android 2.2, Android Webkit Browser.
  674. array(
  675. 'Mozilla/5.0 (Android 2.2; Windows; U; Windows NT 6.1; en-US) AppleWebKit/533.19.4 (KHTML, like Gecko) Version/5.0.3 Safari/533.19.4',
  676. true,
  677. ),
  678. // BlackBerry 9900, BlackBerry browser.
  679. array(
  680. 'Mozilla/5.0 (BlackBerry; U; BlackBerry 9900; en) AppleWebKit/534.11+ (KHTML, like Gecko) Version/7.1.0.346 Mobile Safari/534.11+',
  681. true,
  682. ),
  683. // Windows Phone 8.0, Internet Explorer 10.0.
  684. array(
  685. 'Mozilla/5.0 (compatible; MSIE 10.0; Windows Phone 8.0; Trident/6.0; IEMobile/10.0; ARM; Touch; NOKIA; Lumia 920)',
  686. true,
  687. ),
  688. // Ubuntu desktop, Firefox 41.0.
  689. array(
  690. 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:41.0) Gecko/20100101 Firefox/41.0',
  691. true,
  692. ),
  693. );
  694. }
  695. /**
  696. * @ticket 9064
  697. */
  698. function test_wp_extract_urls() {
  699. $original_urls = array(
  700. 'http://woo.com/1,2,3,4,5,6/-1-2-3-4-/woo.html',
  701. 'http://this.com',
  702. 'http://127.0.0.1',
  703. 'http://www111.urwyeoweytwutreyytqytwetowteuiiu.com/?346236346326&2134362574863.437',
  704. 'http://wordpress-core/1,2,3,4,5,6/-1-2-3-4-/woo.html',
  705. 'http://wordpress-core.com:8080/',
  706. 'http://www.website.com:5000',
  707. 'http://wordpress-core/?346236346326&2134362574863.437',
  708. 'http://افغانستا.icom.museum',
  709. 'http://الجزائر.icom.museum',
  710. 'http://österreich.icom.museum',
  711. 'http://বাংলাদেশ.icom.museum',
  712. 'http://беларусь.icom.museum',
  713. 'http://belgië.icom.museum',
  714. 'http://българия.icom.museum',
  715. 'http://تشادر.icom.museum',
  716. 'http://中国.icom.museum',
  717. // 'http://القمر.icom.museum', // Comoros http://القمر.icom.museum
  718. // 'http://κυπρος.icom.museum', // Cyprus http://κυπρος.icom.museum
  719. 'http://českárepublika.icom.museum',
  720. // 'http://مصر.icom.museum', // Egypt http://مصر.icom.museum
  721. 'http://ελλάδα.icom.museum',
  722. 'http://magyarország.icom.museum',
  723. 'http://ísland.icom.museum',
  724. 'http://भारत.icom.museum',
  725. 'http://ايران.icom.museum',
  726. 'http://éire.icom.museum',
  727. 'http://איקו״ם.ישראל.museum',
  728. 'http://日本.icom.museum',
  729. 'http://الأردن.icom.museum',
  730. 'http://қазақстан.icom.museum',
  731. 'http://한국.icom.museum',
  732. 'http://кыргызстан.icom.museum',
  733. 'http://ລາວ.icom.museum',
  734. 'http://لبنان.icom.museum',
  735. 'http://македонија.icom.museum',
  736. // 'http://موريتانيا.icom.museum', // Mauritania http://موريتانيا.icom.museum
  737. 'http://méxico.icom.museum',
  738. 'http://монголулс.icom.museum',
  739. // 'http://المغرب.icom.museum', // Morocco http://المغرب.icom.museum
  740. 'http://नेपाल.icom.museum',
  741. // 'http://عمان.icom.museum', // Oman http://عمان.icom.museum
  742. 'http://قطر.icom.museum',
  743. 'http://românia.icom.museum',
  744. 'http://россия.иком.museum',
  745. 'http://србијаицрнагора.иком.museum',
  746. 'http://இலங்கை.icom.museum',
  747. 'http://españa.icom.museum',
  748. 'http://ไทย.icom.museum',
  749. 'http://تونس.icom.museum',
  750. 'http://türkiye.icom.museum',
  751. 'http://украина.icom.museum',
  752. 'http://việtnam.icom.museum',
  753. 'ftp://127.0.0.1/',
  754. 'http://www.woo.com/video?v=exvUH2qKLTU',
  755. 'http://taco.com?burrito=enchilada#guac',
  756. );
  757. $blob = '
  758. http://woo.com/1,2,3,4,5,6/-1-2-3-4-/woo.html
  759. http://this.com
  760. http://127.0.0.1
  761. http://www111.urwyeoweytwutreyytqytwetowteuiiu.com/?346236346326&amp;2134362574863.437
  762. http://wordpress-core/1,2,3,4,5,6/-1-2-3-4-/woo.html
  763. http://wordpress-core.com:8080/
  764. http://www.website.com:5000
  765. http://wordpress-core/?346236346326&amp;2134362574863.437
  766. http://افغانستا.icom.museum
  767. http://الجزائر.icom.museum
  768. http://österreich.icom.museum
  769. http://বাংলাদেশ.icom.museum
  770. http://беларусь.icom.museum
  771. http://belgië.icom.museum
  772. http://българия.icom.museum
  773. http://تشادر.icom.museum
  774. http://中国.icom.museum
  775. http://českárepublika.icom.museum
  776. http://ελλάδα.icom.museum
  777. http://magyarország.icom.museum
  778. http://ísland.icom.museum
  779. http://भारत.icom.museum
  780. http://ايران.icom.museum
  781. http://éire.icom.museum
  782. http://איקו״ם.ישראל.museum
  783. http://日本.icom.museum
  784. http://الأردن.icom.museum
  785. http://қазақстан.icom.museum
  786. http://한국.icom.museum
  787. http://кыргызстан.icom.museum
  788. http://ລາວ.icom.museum
  789. http://لبنان.icom.museum
  790. http://македонија.icom.museum
  791. http://méxico.icom.museum
  792. http://монголулс.icom.museum
  793. http://नेपाल.icom.museum
  794. http://قطر.icom.museum
  795. http://românia.icom.museum
  796. http://россия.иком.museum
  797. http://србијаицрнагора.иком.museum
  798. http://இலங்கை.icom.museum
  799. http://españa.icom.museum
  800. http://ไทย.icom.museum
  801. http://تونس.icom.museum
  802. http://türkiye.icom.museum
  803. http://украина.icom.museum
  804. http://việtnam.icom.museum
  805. ftp://127.0.0.1/
  806. http://www.woo.com/video?v=exvUH2qKLTU
  807. http://taco.com?burrito=enchilada#guac
  808. ';
  809. $urls = wp_extract_urls( $blob );
  810. $this->assertNotEmpty( $urls );
  811. $this->assertInternalType( 'array', $urls );
  812. $this->assertCount( count( $original_urls ), $urls );
  813. $this->assertSame( $original_urls, $urls );
  814. $exploded = array_values( array_filter( array_map( 'trim', explode( "\n", $blob ) ) ) );
  815. // wp_extract_urls() calls html_entity_decode().
  816. $decoded = array_map( 'html_entity_decode', $exploded );
  817. $this->assertSame( $decoded, $urls );
  818. $this->assertSame( $original_urls, $decoded );
  819. $blob = 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
  820. incididunt ut labore http://woo.com/1,2,3,4,5,6/-1-2-3-4-/woo.html et dolore magna aliqua.
  821. Ut http://this.com enim ad minim veniam, quis nostrud exercitation 16.06. to 18.06.2014 ullamco http://127.0.0.1
  822. laboris nisi ut aliquip ex http://www111.urwyeoweytwutreyytqytwetowteuiiu.com/?346236346326&amp;2134362574863.437 ea
  823. commodo consequat. http://wordpress-core/1,2,3,4,5,6/-1-2-3-4-/woo.html Duis aute irure dolor in reprehenderit in voluptate
  824. velit esse http://wordpress-core.com:8080/ cillum dolore eu fugiat nulla <A href="http://www.website.com:5000">http://www.website.com:5000</B> pariatur. Excepteur sint occaecat cupidatat non proident,
  825. sunt in culpa qui officia deserunt mollit http://wordpress-core/?346236346326&amp;2134362574863.437 anim id est laborum.';
  826. $urls = wp_extract_urls( $blob );
  827. $this->assertNotEmpty( $urls );
  828. $this->assertInternalType( 'array', $urls );
  829. $this->assertCount( 8, $urls );
  830. $this->assertSame( array_slice( $original_urls, 0, 8 ), $urls );
  831. $blob = 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
  832. incididunt ut labore <a href="http://woo.com/1,2,3,4,5,6/-1-2-3-4-/woo.html">343462^</a> et dolore magna aliqua.
  833. Ut <a href="http://this.com">&amp;3640i6p1yi499</a> enim ad minim veniam, quis nostrud exercitation 16.06. to 18.06.2014 ullamco <a href="http://127.0.0.1">localhost</a>
  834. laboris nisi ut aliquip ex <a href="http://www111.urwyeoweytwutreyytqytwetowteuiiu.com/?346236346326&amp;2134362574863.437">343462^</a> ea
  835. commodo consequat. <a href="http://wordpress-core/1,2,3,4,5,6/-1-2-3-4-/woo.html">343462^</a> Duis aute irure dolor in reprehenderit in voluptate
  836. velit esse <a href="http://wordpress-core.com:8080/">-3-4--321-64-4@#!$^$!@^@^</a> cillum dolore eu <A href="http://www.website.com:5000">http://www.website.com:5000</B> fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident,
  837. sunt in culpa qui officia deserunt mollit <a href="http://wordpress-core/?346236346326&amp;2134362574863.437">)(*&^%$</a> anim id est laborum.';
  838. $urls = wp_extract_urls( $blob );
  839. $this->assertNotEmpty( $urls );
  840. $this->assertInternalType( 'array', $urls );
  841. $this->assertCount( 8, $urls );
  842. $this->assertSame( array_slice( $original_urls, 0, 8 ), $urls );
  843. }
  844. /**
  845. * @ticket 28786
  846. */
  847. function test_wp_json_encode() {
  848. $this->assertSame( wp_json_encode( 'a' ), '"a"' );
  849. }
  850. /**
  851. * @ticket 28786
  852. */
  853. function test_wp_json_encode_utf8() {
  854. $this->assertSame( wp_json_encode( '这' ), '"\u8fd9"' );
  855. }
  856. /**
  857. * @ticket 28786
  858. * @requires function mb_detect_order
  859. */
  860. function test_wp_json_encode_non_utf8() {
  861. $charsets = mb_detect_order();
  862. $old_charsets = $charsets;
  863. if ( ! in_array( 'EUC-JP', $charsets, true ) ) {
  864. $charsets[] = 'EUC-JP';
  865. mb_detect_order( $charsets );
  866. }
  867. $eucjp = mb_convert_encoding( 'aあb', 'EUC-JP', 'UTF-8' );
  868. $utf8 = mb_convert_encoding( $eucjp, 'UTF-8', 'EUC-JP' );
  869. $this->assertSame( 'aあb', $utf8 );
  870. $this->assertSame( '"a\u3042b"', wp_json_encode( $eucjp ) );
  871. mb_detect_order( $old_charsets );
  872. }
  873. /**
  874. * @ticket 28786
  875. * @requires function mb_detect_order
  876. */
  877. function test_wp_json_encode_non_utf8_in_array() {
  878. $charsets = mb_detect_order();
  879. $old_charsets = $charsets;
  880. if ( ! in_array( 'EUC-JP', $charsets, true ) ) {
  881. $charsets[] = 'EUC-JP';
  882. mb_detect_order( $charsets );
  883. }
  884. $eucjp = mb_convert_encoding( 'aあb', 'EUC-JP', 'UTF-8' );
  885. $utf8 = mb_convert_encoding( $eucjp, 'UTF-8', 'EUC-JP' );
  886. $this->assertSame( 'aあb', $utf8 );
  887. $this->assertSame( '["c","a\u3042b"]', wp_json_encode( array( 'c', $eucjp ) ) );
  888. mb_detect_order( $old_charsets );
  889. }
  890. /**
  891. * @ticket 28786
  892. */
  893. function test_wp_json_encode_array() {
  894. $this->assertSame( wp_json_encode( array( 'a' ) ), '["a"]' );
  895. }
  896. /**
  897. * @ticket 28786
  898. */
  899. function test_wp_json_encode_object() {
  900. $object = new stdClass;
  901. $object->a = 'b';
  902. $this->assertSame( wp_json_encode( $object ), '{"a":"b"}' );
  903. }
  904. /**
  905. * @ticket 28786
  906. */
  907. function test_wp_json_encode_depth() {
  908. $data = array( array( array( 1, 2, 3 ) ) );
  909. $json = wp_json_encode( $data, 0, 1 );
  910. $this->assertFalse( $json );
  911. $data = array( 'あ', array( array( 1, 2, 3 ) ) );
  912. $json = wp_json_encode( $data, 0, 1 );
  913. $this->assertFalse( $json );
  914. }
  915. /**
  916. * @ticket 36054
  917. * @dataProvider datetime_provider
  918. */
  919. function test_mysql_to_rfc3339( $expected, $actual ) {
  920. $date_return = mysql_to_rfc3339( $actual );
  921. $this->assertTrue( is_string( $date_return ), 'The date return must be a string' );
  922. $this->assertNotEmpty( $date_return, 'The date return could not be an empty string' );
  923. $this->assertSame( $expected, $date_return, 'The date does not match' );
  924. $this->assertEquals( new DateTime( $expected ), new DateTime( $date_return ), 'The date is not the same after the call method' );
  925. }
  926. function datetime_provider() {
  927. return array(
  928. array( '2016-03-15T18:54:46', '15-03-2016 18:54:46' ),
  929. array( '2016-03-02T19:13:25', '2016-03-02 19:13:25' ),
  930. array( '2016-03-02T19:13:00', '2016-03-02 19:13' ),
  931. array( '2016-03-02T19:13:00', '16-03-02 19:13' ),
  932. array( '2016-03-02T19:13:00', '16-03-02 19:13' ),
  933. );
  934. }
  935. /**
  936. * @ticket 35987
  937. */
  938. public function test_wp_get_ext_types() {
  939. $extensions = wp_get_ext_types();
  940. $this->assertInternalType( 'array', $extensions );
  941. $this->assertNotEmpty( $extensions );
  942. add_filter( 'ext2type', '__return_empty_array' );
  943. $extensions = wp_get_ext_types();
  944. $this->assertSame( array(), $extensions );
  945. remove_filter( 'ext2type', '__return_empty_array' );
  946. $extensions = wp_get_ext_types();
  947. $this->assertInternalType( 'array', $extensions );
  948. $this->assertNotEmpty( $extensions );
  949. }
  950. /**
  951. * @ticket 35987
  952. */
  953. public function test_wp_ext2type() {
  954. $extensions = wp_get_ext_types();
  955. foreach ( $extensions as $type => $extension_list ) {
  956. foreach ( $extension_list as $extension ) {
  957. $this->assertSame( $type, wp_ext2type( $extension ) );
  958. $this->assertSame( $type, wp_ext2type( strtoupper( $extension ) ) );
  959. }
  960. }
  961. $this->assertNull( wp_ext2type( 'unknown_format' ) );
  962. }
  963. /**
  964. * Tests raising the memory limit.
  965. *
  966. * Unfortunately as the default for 'WP_MAX_MEMORY_LIMIT' in the
  967. * test suite is -1, we can not test the memory limit negotiations.
  968. *
  969. * @ticket 32075
  970. */
  971. function test_wp_raise_memory_limit() {
  972. if ( -1 !== WP_MAX_MEMORY_LIMIT ) {
  973. $this->markTestSkipped( 'WP_MAX_MEMORY_LIMIT should be set to -1.' );
  974. }
  975. $ini_limit_before = ini_get( 'memory_limit' );
  976. $raised_limit = wp_raise_memory_limit();
  977. $ini_limit_after = ini_get( 'memory_limit' );
  978. $this->assertSame( $ini_limit_before, $ini_limit_after );
  979. $this->assertFalse( $raised_limit );
  980. $this->assertEquals( WP_MAX_MEMORY_LIMIT, $ini_limit_after );
  981. }
  982. /**
  983. * Tests wp_generate_uuid4().
  984. *
  985. * @covers ::wp_generate_uuid4
  986. * @ticket 38164
  987. */
  988. function test_wp_generate_uuid4() {
  989. $uuids = array();
  990. for ( $i = 0; $i < 20; $i += 1 ) {
  991. $uuid = wp_generate_uuid4();
  992. $this->assertTrue( wp_is_uuid( $uuid, 4 ) );
  993. $uuids[] = $uuid;
  994. }
  995. $unique_uuids = array_unique( $uuids );
  996. $this->assertSame( $uuids, $unique_uuids );
  997. }
  998. /**
  999. * Tests wp_is_uuid().
  1000. *
  1001. * @covers ::wp_is_uuid
  1002. * @ticket 39778
  1003. */
  1004. function test_wp_is_valid_uuid() {
  1005. $uuids_v4 = array(
  1006. '27fe2421-780c-44c5-b39b-fff753092b55',
  1007. 'b7c7713a-4ee9-45a1-87ed-944a90390fc7',
  1008. 'fbedbe35-7bf5-49cc-a5ac-0343bd94360a',
  1009. '4c58e67e-123b-4290-a41c-5eeb6970fa3e',
  1010. 'f54f5b78-e414-4637-84a9-a6cdc94a1beb',
  1011. 'd1c533ac-abcf-44b6-9b0e-6477d2c91b09',
  1012. '7fcd683f-e5fd-454a-a8b9-ed15068830da',
  1013. '7962c750-e58c-470a-af0d-ec1eae453ff2',
  1014. 'a59878ce-9a67-4493-8ca0-a756b52804b3',
  1015. '6faa519d-1e13-4415-bd6f-905ae3689d1d',
  1016. );
  1017. foreach ( $uuids_v4 as $uuid ) {
  1018. $this->assertTrue( wp_is_uuid( $uuid, 4 ) );
  1019. }
  1020. $uuids = array(
  1021. '00000000-0000-0000-0000-000000000000', // Nil.
  1022. '9e3a0460-d72d-11e4-a631-c8e0eb141dab', // Version 1.
  1023. '2c1d43b8-e6d7-376e-af7f-d4bde997cc3f', // Version 3.
  1024. '39888f87-fb62-5988-a425-b2ea63f5b81e', // Version 5.
  1025. );
  1026. foreach ( $uuids as $uuid ) {
  1027. $this->assertTrue( wp_is_uuid( $uuid ) );
  1028. $this->assertFalse( wp_is_uuid( $uuid, 4 ) );
  1029. }
  1030. $invalid_uuids = array(
  1031. 'a19d5192-ea41-41e6-b006',
  1032. 'this-is-not-valid',
  1033. 1234,
  1034. true,
  1035. array(),
  1036. );
  1037. foreach ( $invalid_uuids as $invalid_uuid ) {
  1038. $this->assertFalse( wp_is_uuid( $invalid_uuid, 4 ) );
  1039. $this->assertFalse( wp_is_uuid( $invalid_uuid ) );
  1040. }
  1041. }
  1042. /**
  1043. * Tests wp_unique_id().
  1044. *
  1045. * @covers ::wp_unique_id
  1046. * @ticket 44883
  1047. */
  1048. function test_wp_unique_id() {
  1049. // Test without prefix.
  1050. $ids = array();
  1051. for ( $i = 0; $i < 20; $i += 1 ) {
  1052. $id = wp_unique_id();
  1053. $this->assertInternalType( 'string', $id );
  1054. $this->assertTrue( is_numeric( $id ) );
  1055. $ids[] = $id;
  1056. }
  1057. $this->assertSame( $ids, array_unique( $ids ) );
  1058. // Test with prefix.
  1059. $ids = array();
  1060. for ( $i = 0; $i < 20; $i += 1 ) {
  1061. $id = wp_unique_id( 'foo-' );
  1062. $this->assertRegExp( '/^foo-\d+$/', $id );
  1063. $ids[] = $id;
  1064. }
  1065. $this->assertSame( $ids, array_unique( $ids ) );
  1066. }
  1067. /**
  1068. * @ticket 40017
  1069. * @dataProvider _wp_get_image_mime
  1070. */
  1071. public function test_wp_get_image_mime( $file, $expected ) {
  1072. if ( ! is_callable( 'exif_imagetype' ) && ! function_exists( 'getimagesize' ) ) {
  1073. $this->markTestSkipped( 'The exif PHP extension is not loaded.' );
  1074. }
  1075. $this->assertSame( $expected, wp_get_image_mime( $file ) );
  1076. }
  1077. /**
  1078. * @ticket 39550
  1079. * @dataProvider _wp_check_filetype_and_ext_data
  1080. * @requires extension fileinfo
  1081. */
  1082. function test_wp_check_filetype_and_ext( $file, $filename, $expected ) {
  1083. $this->assertSame( $expected, wp_check_filetype_and_ext( $file, $filename ) );
  1084. }
  1085. /**
  1086. * @ticket 39550
  1087. * @group ms-excluded
  1088. * @requires extension fileinfo
  1089. */
  1090. function test_wp_check_filetype_and_ext_with_filtered_svg() {
  1091. $file = DIR_TESTDATA . '/uploads/video-play.svg';
  1092. $filename = 'video-play.svg';
  1093. $expected = array(
  1094. 'ext' => 'svg',
  1095. 'type' => 'image/svg+xml',
  1096. 'proper_filename' => false,
  1097. );
  1098. add_filter( 'upload_mimes', array( $this, '_filter_mime_types_svg' ) );
  1099. $this->assertSame( $expected, wp_check_filetype_and_ext( $file, $filename ) );
  1100. // Cleanup.
  1101. remove_filter( 'upload_mimes', array( $this, '_test_add_mime_types_svg' ) );
  1102. }
  1103. /**
  1104. * @ticket 39550
  1105. * @group ms-excluded
  1106. * @requires extension fileinfo
  1107. */
  1108. function test_wp_check_filetype_and_ext_with_filtered_woff() {
  1109. $file = DIR_TESTDATA . '/uploads/dashicons.woff';
  1110. $filename = 'dashicons.woff';
  1111. $expected = array(
  1112. 'ext' => 'woff',
  1113. 'type' => 'application/font-woff',
  1114. 'proper_filename' => false,
  1115. );
  1116. add_filter( 'upload_mimes', array( $this, '_filter_mime_types_woff' ) );
  1117. $this->assertSame( $expected, wp_check_filetype_and_ext( $file, $filename ) );
  1118. // Cleanup.
  1119. remove_filter( 'upload_mimes', array( $this, '_test_add_mime_types_woff' ) );
  1120. }
  1121. public function _filter_mime_types_svg( $mimes ) {
  1122. $mimes['svg'] = 'image/svg+xml';
  1123. return $mimes;
  1124. }
  1125. public function _filter_mime_types_woff( $mimes ) {
  1126. $mimes['woff'] = 'application/font-woff';
  1127. return $mimes;
  1128. }
  1129. /**
  1130. * Data provider for test_wp_get_image_mime();
  1131. */
  1132. public function _wp_get_image_mime() {
  1133. $data = array(
  1134. // Standard JPEG.
  1135. array(
  1136. DIR_TESTDATA . '/images/test-image.jpg',
  1137. 'image/jpeg',
  1138. ),
  1139. // Standard GIF.
  1140. array(
  1141. DIR_TESTDATA . '/images/test-image.gif',
  1142. 'image/gif',
  1143. ),
  1144. // Standard PNG.
  1145. array(
  1146. DIR_TESTDATA . '/images/test-image.png',
  1147. 'image/png',
  1148. ),
  1149. // Image with wrong extension.
  1150. array(
  1151. DIR_TESTDATA . '/images/test-image-mime-jpg.png',
  1152. 'image/jpeg',
  1153. ),
  1154. // Not an image.
  1155. array(
  1156. DIR_TESTDATA . '/uploads/dashicons.woff',
  1157. false,
  1158. ),
  1159. );
  1160. return $data;
  1161. }
  1162. public function _wp_check_filetype_and_ext_data() {
  1163. $data = array(
  1164. // Standard image.
  1165. array(
  1166. DIR_TESTDATA . '/images/canola.jpg',
  1167. 'canola.jpg',
  1168. array(
  1169. 'ext' => 'jpg',
  1170. 'type' => 'image/jpeg',
  1171. 'proper_filename' => false,
  1172. ),
  1173. ),
  1174. // Image with wrong extension.
  1175. array(
  1176. DIR_TESTDATA . '/images/test-image-mime-jpg.png',
  1177. 'test-image-mime-jpg.png',
  1178. array(
  1179. 'ext' => 'jpg',
  1180. 'type' => 'image/jpeg',
  1181. 'proper_filename' => 'test-image-mime-jpg.jpg',
  1182. ),
  1183. ),
  1184. // Image without extension.
  1185. array(
  1186. DIR_TESTDATA . '/images/test-image-no-extension',
  1187. 'test-image-no-extension',
  1188. array(
  1189. 'ext' => false,
  1190. 'type' => false,
  1191. 'proper_filename' => false,
  1192. ),
  1193. ),
  1194. // Valid non-image file with an image extension.
  1195. array(
  1196. DIR_TESTDATA . '/formatting/big5.txt',
  1197. 'big5.jpg',
  1198. array(
  1199. 'ext' => false,
  1200. 'type' => false,
  1201. 'proper_filename' => false,
  1202. ),
  1203. ),
  1204. // Non-image file not allowed.
  1205. array(
  1206. DIR_TESTDATA . '/export/crazy-cdata.xml',
  1207. 'crazy-cdata.xml',
  1208. array(
  1209. 'ext' => false,
  1210. 'type' => false,
  1211. 'proper_filename' => false,
  1212. ),
  1213. ),
  1214. // Non-image file not allowed even if it's named like one.
  1215. array(
  1216. DIR_TESTDATA . '/export/crazy-cdata.xml',
  1217. 'crazy-cdata.jpg',
  1218. array(
  1219. 'ext' => false,
  1220. 'type' => false,
  1221. 'proper_filename' => false,
  1222. ),
  1223. ),
  1224. // Non-image file not allowed if it's named like something else.
  1225. array(
  1226. DIR_TESTDATA . '/export/crazy-cdata.xml',
  1227. 'crazy-cdata.doc',
  1228. array(
  1229. 'ext' => false,
  1230. 'type' => false,
  1231. 'proper_filename' => false,
  1232. ),
  1233. ),
  1234. // Non-image file not allowed even if it's named like one.
  1235. array(
  1236. DIR_TESTDATA . '/export/crazy-cdata.xml',
  1237. 'crazy-cdata.jpg',
  1238. array(
  1239. 'ext' => false,
  1240. 'type' => false,
  1241. 'proper_filename' => false,
  1242. ),
  1243. ),
  1244. // Non-image file not allowed if it's named like something else.
  1245. array(
  1246. DIR_TESTDATA . '/export/crazy-cdata.xml',
  1247. 'crazy-cdata.doc',
  1248. array(
  1249. 'ext' => false,
  1250. 'type' => false,
  1251. 'proper_filename' => false,
  1252. ),
  1253. ),
  1254. );
  1255. // Test a few additional file types on single sites.
  1256. if ( ! is_multisite() ) {
  1257. $data = array_merge(
  1258. $data,
  1259. array(
  1260. // Standard non-image file.
  1261. array(
  1262. DIR_TESTDATA . '/formatting/big5.txt',
  1263. 'big5.txt',
  1264. array(
  1265. 'ext' => 'txt',
  1266. 'type' => 'text/plain',
  1267. 'proper_filename' => false,
  1268. ),
  1269. ),
  1270. // Non-image file with wrong sub-type.
  1271. array(
  1272. DIR_TESTDATA . '/uploads/pages-to-word.docx',
  1273. 'pages-to-word.docx',
  1274. array(
  1275. 'ext' => 'docx',
  1276. 'type' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
  1277. 'proper_filename' => false,
  1278. ),
  1279. ),
  1280. // FLAC file.
  1281. array(
  1282. DIR_TESTDATA . '/uploads/small-audio.flac',
  1283. 'small-audio.flac',
  1284. array(
  1285. 'ext' => 'flac',
  1286. 'type' => 'audio/flac',
  1287. 'proper_filename' => false,
  1288. ),
  1289. ),
  1290. // Assorted text/* sample files
  1291. array(
  1292. DIR_TESTDATA . '/uploads/test.vtt',
  1293. 'test.vtt',
  1294. array(
  1295. 'ext' => 'vtt',
  1296. 'type' => 'text/vtt',
  1297. 'proper_filename' => false,
  1298. ),
  1299. ),
  1300. array(
  1301. DIR_TESTDATA . '/uploads/test.csv',
  1302. 'test.csv',
  1303. array(
  1304. 'ext' => 'csv',
  1305. 'type' => 'text/csv',
  1306. 'proper_filename' => false,
  1307. ),
  1308. ),
  1309. // RTF files.
  1310. array(
  1311. DIR_TESTDATA . '/uploads/test.rtf',
  1312. 'test.rtf',
  1313. array(
  1314. 'ext' => 'rtf',
  1315. 'type' => 'application/rtf',
  1316. 'proper_filename' => false,
  1317. ),
  1318. ),
  1319. )
  1320. );
  1321. }
  1322. return $data;
  1323. }
  1324. /**
  1325. * Test file path validation
  1326. *
  1327. * @ticket 42016
  1328. * @dataProvider data_test_validate_file()
  1329. *
  1330. * @param string $file File path.
  1331. * @param array $allowed_files List of allowed files.
  1332. * @param int $expected Expected result.
  1333. */
  1334. public function test_validate_file( $file, $allowed_files, $expected ) {
  1335. $this->assertSame( $expected, validate_file( $file, $allowed_files ) );
  1336. }
  1337. /**
  1338. * Data provider for file validation.
  1339. *
  1340. * @return array {
  1341. * @type array $0... {
  1342. * @type string $0 File path.
  1343. * @type array $1 List of allowed files.
  1344. * @type int $2 Expected result.
  1345. * }
  1346. * }
  1347. */
  1348. public function data_test_validate_file() {
  1349. return array(
  1350. // Allowed files:
  1351. array(
  1352. null,
  1353. array(),
  1354. 0,
  1355. ),
  1356. array(
  1357. '',
  1358. array(),
  1359. 0,
  1360. ),
  1361. array(
  1362. ' ',
  1363. array(),
  1364. 0,
  1365. ),
  1366. array(
  1367. '.',
  1368. array(),
  1369. 0,
  1370. ),
  1371. array(
  1372. '..',
  1373. array(),
  1374. 0,
  1375. ),
  1376. array(
  1377. './',
  1378. array(),
  1379. 0,
  1380. ),
  1381. array(
  1382. 'foo.ext',
  1383. array( 'foo.ext' ),
  1384. 0,
  1385. ),
  1386. array(
  1387. 'dir/foo.ext',
  1388. array(),
  1389. 0,
  1390. ),
  1391. array(
  1392. 'foo..ext',
  1393. array(),
  1394. 0,
  1395. ),
  1396. array(
  1397. 'dir/dir/../',
  1398. array(),
  1399. 0,
  1400. ),
  1401. // Directory traversal:
  1402. array(
  1403. '../',
  1404. array(),
  1405. 1,
  1406. ),
  1407. array(
  1408. '../../',
  1409. array(),
  1410. 1,
  1411. ),
  1412. array(
  1413. '../file.ext',
  1414. array(),
  1415. 1,
  1416. ),
  1417. array(
  1418. '../dir/../',
  1419. array(),
  1420. 1,
  1421. ),
  1422. array(
  1423. '/dir/dir/../../',
  1424. array(),
  1425. 1,
  1426. ),
  1427. array(
  1428. '/dir/dir/../../',
  1429. array( '/dir/dir/../../' ),
  1430. 1,
  1431. ),
  1432. // Windows drives:
  1433. array(
  1434. 'c:',
  1435. array(),
  1436. 2,
  1437. ),
  1438. array(
  1439. 'C:/WINDOWS/system32',
  1440. array( 'C:/WINDOWS/system32' ),
  1441. 2,
  1442. ),
  1443. // Disallowed files:
  1444. array(
  1445. 'foo.ext',
  1446. array( 'bar.ext' ),
  1447. 3,
  1448. ),
  1449. array(
  1450. 'foo.ext',
  1451. array( '.ext' ),
  1452. 3,
  1453. ),
  1454. array(
  1455. 'path/foo.ext',
  1456. array( 'foo.ext' ),
  1457. 3,
  1458. ),
  1459. );
  1460. }
  1461. /**
  1462. * Test stream URL validation.
  1463. *
  1464. * @dataProvider data_test_wp_is_stream
  1465. *
  1466. * @param string $path The resource path or URL.
  1467. * @param bool $expected Expected result.
  1468. */
  1469. public function test_wp_is_stream( $path, $expected ) {
  1470. if ( ! extension_loaded( 'openssl' ) && false !== strpos( $path, 'https://' ) ) {
  1471. $this->markTestSkipped( 'The openssl PHP extension is not loaded.' );
  1472. }
  1473. $this->assertSame( $expected, wp_is_stream( $path ) );
  1474. }
  1475. /**
  1476. * Data provider for stream URL validation.
  1477. *
  1478. * @return array {
  1479. * @type array $0... {
  1480. * @type string $0 The resource path or URL.
  1481. * @type bool $1 Expected result.
  1482. * }
  1483. * }
  1484. */
  1485. public function data_test_wp_is_stream() {
  1486. return array(
  1487. // Legitimate stream examples.
  1488. array( 'http://example.com', true ),
  1489. array( 'https://example.com', true ),
  1490. array( 'ftp://example.com', true ),
  1491. array( 'file:///path/to/some/file', true ),
  1492. array( 'php://some/php/file.php', true ),
  1493. // Non-stream examples.
  1494. array( 'fakestream://foo/bar/baz', false ),
  1495. array( '../../some/relative/path', false ),
  1496. array( 'some/other/relative/path', false ),
  1497. array( '/leading/relative/path', false ),
  1498. );
  1499. }
  1500. /**
  1501. * Test human_readable_duration().
  1502. *
  1503. * @ticket 39667
  1504. * @dataProvider data_test_human_readable_duration
  1505. *
  1506. * @param string $input Duration.
  1507. * @param string $expected Expected human readable duration.
  1508. */
  1509. public function test_human_readable_duration( $input, $expected ) {
  1510. $this->assertSame( $expected, human_readable_duration( $input ) );
  1511. }
  1512. /**
  1513. * Dataprovider for test_duration_format().
  1514. *
  1515. * @return array {
  1516. * @type array {
  1517. * @type string $input Duration.
  1518. * @type string $expect Expected human readable duration.
  1519. * }
  1520. * }
  1521. */
  1522. public function data_test_human_readable_duration() {
  1523. return array(
  1524. // Valid ii:ss cases.
  1525. array( '0:0', '0 minutes, 0 seconds' ),
  1526. array( '00:00', '0 minutes, 0 seconds' ),
  1527. array( '0:5', '0 minutes, 5 seconds' ),
  1528. array( '0:05', '0 minutes, 5 seconds' ),
  1529. array( '01:01', '1 minute, 1 second' ),
  1530. array( '30:00', '30 minutes, 0 seconds' ),
  1531. array( ' 30:00 ', '30 minutes, 0 seconds' ),
  1532. // Valid HH:ii:ss cases.
  1533. array( '0:0:0', '0 hours, 0 minutes, 0 seconds' ),
  1534. array( '00:00:00', '0 hours, 0 minutes, 0 seconds' ),
  1535. array( '00:30:34', '0 hours, 30 minutes, 34 seconds' ),
  1536. array( '01:01:01', '1 hour, 1 minute, 1 second' ),
  1537. array( '1:02:00', '1 hour, 2 minutes, 0 seconds' ),
  1538. array( '10:30:34', '10 hours, 30 minutes, 34 seconds' ),
  1539. array( '1234567890:59:59', '1234567890 hours, 59 minutes, 59 seconds' ),
  1540. // Valid ii:ss cases with negative sign.
  1541. array( '-00:00', '0 minutes, 0 seconds' ),
  1542. array( '-3:00', '3 minutes, 0 seconds' ),
  1543. array( '-03:00', '3 minutes, 0 seconds' ),
  1544. array( '-30:00', '30 minutes, 0 seconds' ),
  1545. // Valid HH:ii:ss cases with negative sign.
  1546. array( '-00:00:00', '0 hours, 0 minutes, 0 seconds' ),
  1547. array( '-1:02:00', '1 hour, 2 minutes, 0 seconds' ),
  1548. // Invalid cases.
  1549. array( null, false ),
  1550. array( '', false ),
  1551. array( ':', false ),
  1552. array( '::', false ),
  1553. array( array(), false ),
  1554. array( 'Batman Begins !', false ),
  1555. array( '', false ),
  1556. array( '-1', false ),
  1557. array( -1, false ),
  1558. array( 0, false ),
  1559. array( 1, false ),
  1560. array( '00', false ),
  1561. array( '30:-10', false ),
  1562. array( ':30:00', false ), // Missing HH.
  1563. array( 'MM:30:00', false ), // Invalid HH.
  1564. array( '30:MM:00', false ), // Invalid ii.
  1565. array( '30:30:MM', false ), // Invalid ss.
  1566. array( '30:MM', false ), // Invalid ss.
  1567. array( 'MM:00', false ), // Invalid ii.
  1568. array( 'MM:MM', false ), // Invalid ii and ss.
  1569. array( '10 :30', false ), // Containing a space.
  1570. array( '59:61', false ), // Out of bound.
  1571. array( '61:59', false ), // Out of bound.
  1572. array( '3:59:61', false ), // Out of bound.
  1573. array( '03:61:59', false ), // Out of bound.
  1574. );
  1575. }
  1576. /**
  1577. * @ticket 49404
  1578. * @dataProvider data_test_wp_is_json_media_type
  1579. */
  1580. public function test_wp_is_json_media_type( $input, $expected ) {
  1581. $this->assertSame( $expected, wp_is_json_media_type( $input ) );
  1582. }
  1583. public function data_test_wp_is_json_media_type() {
  1584. return array(
  1585. array( 'application/ld+json', true ),
  1586. array( 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"', true ),
  1587. array( 'application/activity+json', true ),
  1588. array( 'application/json+oembed', true ),
  1589. array( 'application/json', true ),
  1590. array( 'application/nojson', false ),
  1591. array( 'application/no.json', false ),
  1592. array( 'text/html, application/xhtml+xml, application/xml;q=0.9, image/webp, */*;q=0.8', false ),
  1593. array( 'application/activity+json, application/nojson', true ),
  1594. );
  1595. }
  1596. }