ApiFormatPhpTest.php 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. <?php
  2. /**
  3. * @group API
  4. * @covers ApiFormatPhp
  5. */
  6. class ApiFormatPhpTest extends ApiFormatTestBase {
  7. protected $printerName = 'php';
  8. private static function addFormatVersion( $format, $arr ) {
  9. foreach ( $arr as &$p ) {
  10. if ( !isset( $p[2] ) ) {
  11. $p[2] = [ 'formatversion' => $format ];
  12. } else {
  13. $p[2]['formatversion'] = $format;
  14. }
  15. }
  16. return $arr;
  17. }
  18. public static function provideGeneralEncoding() {
  19. // phpcs:disable Generic.Files.LineLength
  20. return array_merge(
  21. self::addFormatVersion( 1, [
  22. // Basic types
  23. [ [ null ], 'a:1:{i:0;N;}' ],
  24. [ [ true ], 'a:1:{i:0;s:0:"";}' ],
  25. [ [ false ], 'a:0:{}' ],
  26. [ [ true, ApiResult::META_BC_BOOLS => [ 0 ] ],
  27. 'a:1:{i:0;b:1;}' ],
  28. [ [ false, ApiResult::META_BC_BOOLS => [ 0 ] ],
  29. 'a:1:{i:0;b:0;}' ],
  30. [ [ 42 ], 'a:1:{i:0;i:42;}' ],
  31. [ [ 42.5 ], 'a:1:{i:0;d:42.5;}' ],
  32. [ [ 1e42 ], 'a:1:{i:0;d:1.0E+42;}' ],
  33. [ [ 'foo' ], 'a:1:{i:0;s:3:"foo";}' ],
  34. [ [ 'fóo' ], 'a:1:{i:0;s:4:"fóo";}' ],
  35. // Arrays and objects
  36. [ [ [] ], 'a:1:{i:0;a:0:{}}' ],
  37. [ [ [ 1 ] ], 'a:1:{i:0;a:1:{i:0;i:1;}}' ],
  38. [ [ [ 'x' => 1 ] ], 'a:1:{i:0;a:1:{s:1:"x";i:1;}}' ],
  39. [ [ [ 2 => 1 ] ], 'a:1:{i:0;a:1:{i:2;i:1;}}' ],
  40. [ [ (object)[] ], 'a:1:{i:0;a:0:{}}' ],
  41. [ [ [ 1, ApiResult::META_TYPE => 'assoc' ] ], 'a:1:{i:0;a:1:{i:0;i:1;}}' ],
  42. [ [ [ 'x' => 1, ApiResult::META_TYPE => 'array' ] ], 'a:1:{i:0;a:1:{i:0;i:1;}}' ],
  43. [ [ [ 'x' => 1, ApiResult::META_TYPE => 'kvp' ] ], 'a:1:{i:0;a:1:{s:1:"x";i:1;}}' ],
  44. [ [ [ 'x' => 1, ApiResult::META_TYPE => 'BCkvp', ApiResult::META_KVP_KEY_NAME => 'key' ] ],
  45. 'a:1:{i:0;a:1:{i:0;a:2:{s:3:"key";s:1:"x";s:1:"*";i:1;}}}' ],
  46. [ [ [ 'x' => 1, ApiResult::META_TYPE => 'BCarray' ] ], 'a:1:{i:0;a:1:{s:1:"x";i:1;}}' ],
  47. [ [ [ 'a', 'b', ApiResult::META_TYPE => 'BCassoc' ] ], 'a:1:{i:0;a:2:{i:0;s:1:"a";i:1;s:1:"b";}}' ],
  48. // Content
  49. [ [ 'content' => 'foo', ApiResult::META_CONTENT => 'content' ],
  50. 'a:1:{s:1:"*";s:3:"foo";}' ],
  51. // BC Subelements
  52. [ [ 'foo' => 'foo', ApiResult::META_BC_SUBELEMENTS => [ 'foo' ] ],
  53. 'a:1:{s:3:"foo";a:1:{s:1:"*";s:3:"foo";}}' ],
  54. ] ),
  55. self::addFormatVersion( 2, [
  56. // Basic types
  57. [ [ null ], 'a:1:{i:0;N;}' ],
  58. [ [ true ], 'a:1:{i:0;b:1;}' ],
  59. [ [ false ], 'a:1:{i:0;b:0;}' ],
  60. [ [ true, ApiResult::META_BC_BOOLS => [ 0 ] ],
  61. 'a:1:{i:0;b:1;}' ],
  62. [ [ false, ApiResult::META_BC_BOOLS => [ 0 ] ],
  63. 'a:1:{i:0;b:0;}' ],
  64. [ [ 42 ], 'a:1:{i:0;i:42;}' ],
  65. [ [ 42.5 ], 'a:1:{i:0;d:42.5;}' ],
  66. [ [ 1e42 ], 'a:1:{i:0;d:1.0E+42;}' ],
  67. [ [ 'foo' ], 'a:1:{i:0;s:3:"foo";}' ],
  68. [ [ 'fóo' ], 'a:1:{i:0;s:4:"fóo";}' ],
  69. // Arrays and objects
  70. [ [ [] ], 'a:1:{i:0;a:0:{}}' ],
  71. [ [ [ 1 ] ], 'a:1:{i:0;a:1:{i:0;i:1;}}' ],
  72. [ [ [ 'x' => 1 ] ], 'a:1:{i:0;a:1:{s:1:"x";i:1;}}' ],
  73. [ [ [ 2 => 1 ] ], 'a:1:{i:0;a:1:{i:2;i:1;}}' ],
  74. [ [ (object)[] ], 'a:1:{i:0;a:0:{}}' ],
  75. [ [ [ 1, ApiResult::META_TYPE => 'assoc' ] ], 'a:1:{i:0;a:1:{i:0;i:1;}}' ],
  76. [ [ [ 'x' => 1, ApiResult::META_TYPE => 'array' ] ], 'a:1:{i:0;a:1:{i:0;i:1;}}' ],
  77. [ [ [ 'x' => 1, ApiResult::META_TYPE => 'kvp' ] ], 'a:1:{i:0;a:1:{s:1:"x";i:1;}}' ],
  78. [ [ [ 'x' => 1, ApiResult::META_TYPE => 'BCkvp', ApiResult::META_KVP_KEY_NAME => 'key' ] ],
  79. 'a:1:{i:0;a:1:{s:1:"x";i:1;}}' ],
  80. [ [ [ 'x' => 1, ApiResult::META_TYPE => 'BCarray' ] ], 'a:1:{i:0;a:1:{i:0;i:1;}}' ],
  81. [ [ [ 'a', 'b', ApiResult::META_TYPE => 'BCassoc' ] ], 'a:1:{i:0;a:2:{i:0;s:1:"a";i:1;s:1:"b";}}' ],
  82. // Content
  83. [ [ 'content' => 'foo', ApiResult::META_CONTENT => 'content' ],
  84. 'a:1:{s:7:"content";s:3:"foo";}' ],
  85. // BC Subelements
  86. [ [ 'foo' => 'foo', ApiResult::META_BC_SUBELEMENTS => [ 'foo' ] ],
  87. 'a:1:{s:3:"foo";s:3:"foo";}' ],
  88. ] )
  89. );
  90. // phpcs:enable
  91. }
  92. public function testCrossDomainMangling() {
  93. $config = new HashConfig( [ 'MangleFlashPolicy' => false ] );
  94. $context = new RequestContext;
  95. $context->setConfig( new MultiConfig( [
  96. $config,
  97. $context->getConfig(),
  98. ] ) );
  99. $main = new ApiMain( $context );
  100. $main->getResult()->addValue( null, null, '< Cross-Domain-Policy >' );
  101. $printer = $main->createPrinterByName( 'php' );
  102. ob_start( 'MediaWiki\\OutputHandler::handle' );
  103. $printer->initPrinter();
  104. $printer->execute();
  105. $printer->closePrinter();
  106. $ret = ob_get_clean();
  107. $this->assertSame( 'a:1:{i:0;s:23:"< Cross-Domain-Policy >";}', $ret );
  108. $config->set( 'MangleFlashPolicy', true );
  109. $printer = $main->createPrinterByName( 'php' );
  110. ob_start( 'MediaWiki\\OutputHandler::handle' );
  111. try {
  112. $printer->initPrinter();
  113. $printer->execute();
  114. $printer->closePrinter();
  115. ob_end_clean();
  116. $this->fail( 'Expected exception not thrown' );
  117. } catch ( ApiUsageException $ex ) {
  118. ob_end_clean();
  119. $this->assertTrue(
  120. $ex->getStatusValue()->hasMessage( 'apierror-formatphp' ),
  121. 'Expected exception'
  122. );
  123. }
  124. }
  125. }