Fix Display\ResultsTest test on Windows
[phpmyadmin.git] / test / classes / Rte / RoutinesTest.php
blobabcb8ad766b17bf658a676e9c3ae38ac8838faf2
1 <?php
2 /* vim: set expandtab sw=4 ts=4 sts=4: */
3 /**
4 * Tests for PhpMyAdmin\Rte\Routines
6 * @package PhpMyAdmin-test
7 */
8 declare(strict_types=1);
10 namespace PhpMyAdmin\Tests\Rte;
12 use PhpMyAdmin\Config;
13 use PhpMyAdmin\DatabaseInterface;
14 use PhpMyAdmin\Response;
15 use PhpMyAdmin\Rte\Routines;
16 use PhpMyAdmin\Types;
17 use PHPUnit\Framework\TestCase;
19 /**
20 * This class is for testing PhpMyAdmin\Rte\Routines methods
22 * @package PhpMyAdmin-test
24 class RoutinesTest extends TestCase
26 /**
27 * @var Routines
29 private $routines;
31 /**
32 * Set up
34 * @return void
36 protected function setUp(): void
38 $GLOBALS['PMA_Config'] = new Config();
39 $GLOBALS['PMA_Config']->enableBc();
40 $GLOBALS['cfg']['Server']['DisableIS'] = false;
41 $GLOBALS['cfg']['ActionLinksMode'] = 'icons';
42 $GLOBALS['server'] = 0;
43 $GLOBALS['db'] = 'db';
44 $GLOBALS['table'] = 'table';
45 $GLOBALS['PMA_PHP_SELF'] = 'index.php';
47 $this->routines = new Routines($GLOBALS['dbi']);
50 /**
51 * Test for getDataFromRequest
53 * @param array $in Input
54 * @param array $out Expected output
56 * @return void
58 * @dataProvider providerGetDataFromRequest
60 public function testGetDataFromRequest($in, $out): void
62 unset($_POST);
63 unset($_REQUEST);
64 foreach ($in as $key => $value) {
65 if ($value !== '') {
66 $_POST[$key] = $value;
67 $_REQUEST[$key] = $value;
70 $this->routines->setGlobals();
71 $this->assertEquals($out, $this->routines->getDataFromRequest());
74 /**
75 * Data provider for testGetDataFromRequest
77 * @return array
79 public function providerGetDataFromRequest()
81 return [
84 'item_name' => '',
85 'item_original_name' => '',
86 'item_returnlength' => '',
87 'item_returnopts_num' => '',
88 'item_returnopts_text' => '',
89 'item_definition' => '',
90 'item_comment' => '',
91 'item_definer' => '',
92 'item_type' => '',
93 'item_type_toggle' => '',
94 'item_original_type' => '',
95 'item_param_dir' => '',
96 'item_param_name' => '',
97 'item_param_type' => '',
98 'item_param_length' => '',
99 'item_param_opts_num' => '',
100 'item_param_opts_text' => '',
101 'item_returntype' => '',
102 'item_isdeterministic' => '',
103 'item_securitytype' => '',
104 'item_sqldataaccess' => '',
107 'item_name' => '',
108 'item_original_name' => '',
109 'item_returnlength' => '',
110 'item_returnopts_num' => '',
111 'item_returnopts_text' => '',
112 'item_definition' => '',
113 'item_comment' => '',
114 'item_definer' => '',
115 'item_type' => 'PROCEDURE',
116 'item_type_toggle' => 'FUNCTION',
117 'item_original_type' => 'PROCEDURE',
118 'item_num_params' => 0,
119 'item_param_dir' => [],
120 'item_param_name' => [],
121 'item_param_type' => [],
122 'item_param_length' => [],
123 'item_param_opts_num' => [],
124 'item_param_opts_text' => [],
125 'item_returntype' => '',
126 'item_isdeterministic' => '',
127 'item_securitytype_definer' => '',
128 'item_securitytype_invoker' => '',
129 'item_sqldataaccess' => '',
134 'item_name' => 'proc2',
135 'item_original_name' => 'proc',
136 'item_returnlength' => '',
137 'item_returnopts_num' => '',
138 'item_returnopts_text' => '',
139 'item_definition' => 'SELECT NULL',
140 'item_comment' => 'some text',
141 'item_definer' => 'root@localhost',
142 'item_type' => 'PROCEDURE',
143 'item_type_toggle' => 'FUNCTION',
144 'item_original_type' => 'PROCEDURE',
145 'item_param_dir' => [
146 0 => 'IN',
147 1 => 'FAIL',
149 'item_param_name' => [
150 0 => 'bar',
151 1 => 'baz',
153 'item_param_type' => [
154 0 => 'INT',
155 1 => 'FAIL',
157 'item_param_length' => [
158 0 => '20',
159 1 => '',
161 'item_param_opts_num' => [
162 0 => 'UNSIGNED',
163 1 => '',
165 'item_param_opts_text' => [
166 0 => '',
167 1 => 'latin1',
169 'item_returntype' => '',
170 'item_isdeterministic' => 'ON',
171 'item_securitytype' => 'INVOKER',
172 'item_sqldataaccess' => 'NO SQL',
175 'item_name' => 'proc2',
176 'item_original_name' => 'proc',
177 'item_returnlength' => '',
178 'item_returnopts_num' => '',
179 'item_returnopts_text' => '',
180 'item_definition' => 'SELECT NULL',
181 'item_comment' => 'some text',
182 'item_definer' => 'root@localhost',
183 'item_type' => 'PROCEDURE',
184 'item_type_toggle' => 'FUNCTION',
185 'item_original_type' => 'PROCEDURE',
186 'item_num_params' => 2,
187 'item_param_dir' => [
188 0 => 'IN',
189 1 => '',
191 'item_param_name' => [
192 0 => 'bar',
193 1 => 'baz',
195 'item_param_type' => [
196 0 => 'INT',
197 1 => '',
199 'item_param_length' => [
200 0 => '20',
201 1 => '',
203 'item_param_opts_num' => [
204 0 => 'UNSIGNED',
205 1 => '',
207 'item_param_opts_text' => [
208 0 => '',
209 1 => 'latin1',
211 'item_returntype' => '',
212 'item_isdeterministic' => ' checked=\'checked\'',
213 'item_securitytype_definer' => '',
214 'item_securitytype_invoker' => ' selected=\'selected\'',
215 'item_sqldataaccess' => 'NO SQL',
220 'item_name' => 'func2',
221 'item_original_name' => 'func',
222 'item_returnlength' => '20',
223 'item_returnopts_num' => '',
224 'item_returnopts_text' => 'CHARSET utf8',
225 'item_definition' => 'SELECT NULL',
226 'item_comment' => 'some text',
227 'item_definer' => 'root@localhost',
228 'item_type' => 'FUNCTION',
229 'item_type_toggle' => 'PROCEDURE',
230 'item_original_type' => 'FUNCTION',
231 'item_param_dir' => [
232 0 => '',
233 1 => '',
235 'item_param_name' => [
236 0 => 'bar',
237 1 => 'baz',
239 'item_param_type' => [
240 0 => '<s>XSS</s>',
241 1 => 'TEXT',
243 'item_param_length' => [
244 0 => '10,10',
245 1 => '',
247 'item_param_opts_num' => [
248 0 => 'UNSIGNED',
249 1 => '',
251 'item_param_opts_text' => [
252 0 => '',
253 1 => 'utf8',
255 'item_returntype' => 'VARCHAR',
256 'item_isdeterministic' => '',
257 'item_securitytype' => 'DEFINER',
258 'item_sqldataaccess' => '',
261 'item_name' => 'func2',
262 'item_original_name' => 'func',
263 'item_returnlength' => '20',
264 'item_returnopts_num' => '',
265 'item_returnopts_text' => 'CHARSET utf8',
266 'item_definition' => 'SELECT NULL',
267 'item_comment' => 'some text',
268 'item_definer' => 'root@localhost',
269 'item_type' => 'FUNCTION',
270 'item_type_toggle' => 'PROCEDURE',
271 'item_original_type' => 'FUNCTION',
272 'item_num_params' => '2',
273 'item_param_dir' => [],
274 'item_param_name' => [
275 0 => 'bar',
276 1 => 'baz',
278 'item_param_type' => [
279 0 => '',
280 1 => 'TEXT',
282 'item_param_length' => [
283 0 => '10,10',
284 1 => '',
286 'item_param_opts_num' => [
287 0 => 'UNSIGNED',
288 1 => '',
290 'item_param_opts_text' => [
291 0 => '',
292 1 => 'utf8',
294 'item_returntype' => 'VARCHAR',
295 'item_isdeterministic' => '',
296 'item_securitytype_definer' => ' selected=\'selected\'',
297 'item_securitytype_invoker' => '',
298 'item_sqldataaccess' => '',
305 * Test for getParameterRow
307 * @return void
309 public function testGetParameterRowEmpty()
311 $this->routines->setGlobals();
312 $this->assertEquals('', $this->routines->getParameterRow([], 0));
316 * Test for getParameterRow
318 * @param array $data Data for routine
319 * @param mixed $index Index
320 * @param array $matcher Matcher
322 * @return void
324 * @depends testGetParameterRowEmpty
325 * @dataProvider providerGetParameterRow
327 public function testGetParameterRow($data, $index, $matcher): void
329 $this->routines->setGlobals();
330 $this->assertStringContainsString(
331 $matcher,
332 $this->routines->getParameterRow($data, $index)
337 * Data provider for testGetParameterRow
339 * @return array
341 public function providerGetParameterRow()
343 $data = [
344 'item_name' => '',
345 'item_original_name' => '',
346 'item_returnlength' => '',
347 'item_returnopts_num' => '',
348 'item_returnopts_text' => '',
349 'item_definition' => '',
350 'item_comment' => '',
351 'item_definer' => '',
352 'item_type' => 'PROCEDURE',
353 'item_type_toggle' => 'FUNCTION',
354 'item_original_type' => 'PROCEDURE',
355 'item_num_params' => 1,
356 'item_param_dir' => [0 => 'IN'],
357 'item_param_name' => [0 => 'foo'],
358 'item_param_type' => [0 => 'INT'],
359 'item_param_length' => [0 => ''],
360 'item_param_opts_num' => [0 => 'UNSIGNED'],
361 'item_param_opts_text' => [0 => ''],
362 'item_returntype' => '',
363 'item_isdeterministic' => '',
364 'item_securitytype_definer' => '',
365 'item_securitytype_invoker' => '',
366 'item_sqldataaccess' => '',
369 return [
371 $data,
373 '<select name="item_param_dir[0]"',
376 $data,
378 '<input name="item_param_name[0]"',
381 $data,
383 '<select name="item_param_type[0]"',
386 $data,
388 '<select name="item_param_opts_num[0]"',
391 $data,
393 '<a href="#" class="routine_param_remove_anchor"',
399 * Test for getParameterRow
401 * @param array $data Data for routine
402 * @param array $matcher Matcher
404 * @return void
406 * @depends testGetParameterRow
407 * @dataProvider providerGetParameterRowAjax
409 public function testGetParameterRowAjax($data, $matcher): void
411 Response::getInstance()->setAjax(true);
412 $this->routines->setGlobals();
413 $this->assertStringContainsString(
414 $matcher,
415 $this->routines->getParameterRow($data)
417 Response::getInstance()->setAjax(false);
421 * Data provider for testGetParameterRowAjax
423 * @return array
425 public function providerGetParameterRowAjax()
427 $data = [
428 'item_name' => '',
429 'item_original_name' => '',
430 'item_returnlength' => '',
431 'item_returnopts_num' => '',
432 'item_returnopts_text' => '',
433 'item_definition' => '',
434 'item_comment' => '',
435 'item_definer' => '',
436 'item_type' => 'PROCEDURE',
437 'item_type_toggle' => 'FUNCTION',
438 'item_original_type' => 'PROCEDURE',
439 'item_num_params' => 1,
440 'item_param_dir' => [0 => 'IN'],
441 'item_param_name' => [0 => 'foo'],
442 'item_param_type' => [0 => 'INT'],
443 'item_param_length' => [0 => ''],
444 'item_param_opts_num' => [0 => 'UNSIGNED'],
445 'item_param_opts_text' => [0 => ''],
446 'item_returntype' => '',
447 'item_isdeterministic' => '',
448 'item_securitytype_definer' => '',
449 'item_securitytype_invoker' => '',
450 'item_sqldataaccess' => '',
453 return [
455 $data,
456 '<select name="item_param_dir[%s]"',
459 $data,
460 '<input name="item_param_name[%s]"',
463 $data,
464 '<select name="item_param_dir[%s]"',
467 $data,
468 '<select name="item_param_opts_num[%s]"',
471 $data,
472 '<a href="#" class="routine_param_remove_anchor"',
478 * Test for getEditorForm
480 * @param array $data Data for routine
481 * @param array $matcher Matcher
483 * @return void
485 * @depends testGetParameterRowAjax
486 * @dataProvider providerGetEditorForm1
488 public function testGetEditorForm1($data, $matcher)
490 $this->routines->setGlobals();
491 $this->assertStringContainsString(
492 $matcher,
493 $this->routines->getEditorForm('add', '', $data)
498 * Data provider for testGetEditorForm1
500 * @return array
502 public function providerGetEditorForm1()
504 $data = [
505 'item_name' => '',
506 'item_original_name' => '',
507 'item_returnlength' => '',
508 'item_returnopts_num' => '',
509 'item_returnopts_text' => '',
510 'item_definition' => '',
511 'item_comment' => '',
512 'item_definer' => '',
513 'item_type' => 'PROCEDURE',
514 'item_type_toggle' => 'FUNCTION',
515 'item_original_type' => 'PROCEDURE',
516 'item_num_params' => 0,
517 'item_param_dir' => [],
518 'item_param_name' => [],
519 'item_param_type' => [],
520 'item_param_length' => [],
521 'item_param_opts_num' => [],
522 'item_param_opts_text' => [],
523 'item_returntype' => '',
524 'item_isdeterministic' => '',
525 'item_securitytype_definer' => '',
526 'item_securitytype_invoker' => '',
527 'item_sqldataaccess' => '',
530 return [
532 $data,
533 "<input name='add_item'",
536 $data,
537 "<input type='text' name='item_name'",
540 $data,
541 "<input name='item_type'",
544 $data,
545 "name='routine_changetype'",
548 $data,
549 "name='routine_addparameter'",
552 $data,
553 "name='routine_removeparameter'",
556 $data,
557 "select name='item_returntype'",
560 $data,
561 "name='item_returnlength'",
564 $data,
565 "select name='item_returnopts_num'",
568 $data,
569 "<textarea name='item_definition'",
572 $data,
573 "name='item_isdeterministic'",
576 $data,
577 "name='item_definer'",
580 $data,
581 "select name='item_securitytype'",
584 $data,
585 "select name='item_sqldataaccess'",
588 $data,
589 "name='item_comment'",
592 $data,
593 "name='editor_process_add'",
599 * Test for getEditorForm
601 * @param array $data Data for routine
602 * @param array $matcher Matcher
604 * @return void
606 * @depends testGetParameterRowAjax
607 * @dataProvider providerGetEditorForm2
609 public function testGetEditorForm2($data, $matcher)
611 $this->routines->setGlobals();
612 $this->assertStringContainsString(
613 $matcher,
614 $this->routines->getEditorForm('edit', 'change', $data)
619 * Data provider for testGetEditorForm2
621 * @return array
623 public function providerGetEditorForm2()
625 $data = [
626 'item_name' => 'foo',
627 'item_original_name' => 'bar',
628 'item_returnlength' => '',
629 'item_returnopts_num' => '',
630 'item_returnopts_text' => '',
631 'item_definition' => 'SELECT 1',
632 'item_comment' => '',
633 'item_definer' => '',
634 'item_type' => 'PROCEDURE',
635 'item_type_toggle' => 'FUNCTION',
636 'item_original_type' => 'PROCEDURE',
637 'item_num_params' => 1,
638 'item_param_dir' => [0 => 'IN'],
639 'item_param_name' => [0 => 'baz'],
640 'item_param_type' => [0 => 'INT'],
641 'item_param_length' => [0 => '20'],
642 'item_param_opts_num' => [0 => 'UNSIGNED'],
643 'item_param_opts_text' => [0 => ''],
644 'item_returntype' => '',
645 'item_isdeterministic' => '',
646 'item_securitytype_definer' => '',
647 'item_securitytype_invoker' => '',
648 'item_sqldataaccess' => 'NO SQL',
651 return [
653 $data,
654 "name='edit_item'",
657 $data,
658 "name='item_name'",
661 $data,
662 "<input name='item_type' type='hidden' value='FUNCTION'",
665 $data,
666 "name='routine_changetype'",
669 $data,
670 "name='routine_addparameter'",
673 $data,
674 "name='routine_removeparameter'",
677 $data,
678 "name='item_returntype'",
681 $data,
682 "name='item_returnlength'",
685 $data,
686 "name='item_returnopts_num'",
689 $data,
690 "<textarea name='item_definition'",
693 $data,
694 "name='item_isdeterministic'",
697 $data,
698 "name='item_definer'",
701 $data,
702 "<select name='item_securitytype'",
705 $data,
706 "<select name='item_sqldataaccess'",
709 $data,
710 "name='item_comment'",
713 $data,
714 "name='editor_process_edit'",
720 * Test for getEditorForm
722 * @param array $data Data for routine
723 * @param array $matcher Matcher
725 * @return void
727 * @depends testGetParameterRowAjax
728 * @dataProvider providerGetEditorForm3
730 public function testGetEditorForm3($data, $matcher)
732 Response::getInstance()->setAjax(true);
733 $this->routines->setGlobals();
734 $this->assertStringContainsString(
735 $matcher,
736 $this->routines->getEditorForm('edit', 'remove', $data)
738 Response::getInstance()->setAjax(false);
742 * Data provider for testGetEditorForm3
744 * @return array
746 public function providerGetEditorForm3()
748 $data = [
749 'item_name' => 'foo',
750 'item_original_name' => 'bar',
751 'item_returnlength' => '',
752 'item_returnopts_num' => 'UNSIGNED',
753 'item_returnopts_text' => '',
754 'item_definition' => 'SELECT 1',
755 'item_comment' => '',
756 'item_definer' => '',
757 'item_type' => 'FUNCTION',
758 'item_type_toggle' => 'PROCEDURE',
759 'item_original_type' => 'FUNCTION',
760 'item_num_params' => 1,
761 'item_param_dir' => [0 => ''],
762 'item_param_name' => [0 => 'baz'],
763 'item_param_type' => [0 => 'INT'],
764 'item_param_length' => [0 => '20'],
765 'item_param_opts_num' => [0 => 'UNSIGNED'],
766 'item_param_opts_text' => [0 => ''],
767 'item_returntype' => 'INT',
768 'item_isdeterministic' => '',
769 'item_securitytype_definer' => '',
770 'item_securitytype_invoker' => '',
771 'item_sqldataaccess' => 'NO SQL',
774 return [
776 $data,
777 "name='edit_item'",
780 $data,
781 "name='item_name'",
784 $data,
785 "<select name='item_type'",
788 $data,
789 "name='routine_addparameter'",
792 $data,
793 "name='routine_removeparameter'",
796 $data,
797 "<select name='item_returntype'",
800 $data,
801 "name='item_returnlength'",
804 $data,
805 "<select name='item_returnopts_num'",
808 $data,
809 "<textarea name='item_definition'",
812 $data,
813 "name='item_isdeterministic'",
816 $data,
817 "name='item_definer'",
820 $data,
821 "<select name='item_securitytype'",
824 $data,
825 "<select name='item_sqldataaccess'",
828 $data,
829 "name='item_comment'",
832 $data,
833 "name='ajax_request'",
836 $data,
837 "name='editor_process_edit'",
843 * Test for getEditorForm
845 * @param array $data Data for routine
846 * @param array $matcher Matcher
848 * @return void
850 * @depends testGetParameterRowAjax
851 * @dataProvider providerGetEditorForm4
853 public function testGetEditorForm4($data, $matcher)
855 $this->routines->setGlobals();
856 $this->assertStringContainsString(
857 $matcher,
858 $this->routines->getEditorForm('edit', 'change', $data)
863 * Data provider for testGetEditorForm4
865 * @return array
867 public function providerGetEditorForm4()
869 $data = [
870 'item_name' => 'foo',
871 'item_original_name' => 'bar',
872 'item_returnlength' => '',
873 'item_returnopts_num' => '',
874 'item_returnopts_text' => '',
875 'item_definition' => 'SELECT 1',
876 'item_comment' => '',
877 'item_definer' => '',
878 'item_type' => 'FUNCTION',
879 'item_type_toggle' => 'PROCEDURE',
880 'item_original_type' => 'PROCEDURE',
881 'item_num_params' => 1,
882 'item_param_dir' => [0 => 'IN'],
883 'item_param_name' => [0 => 'baz'],
884 'item_param_type' => [0 => 'INT'],
885 'item_param_length' => [0 => '20'],
886 'item_param_opts_num' => [0 => 'UNSIGNED'],
887 'item_param_opts_text' => [0 => ''],
888 'item_returntype' => '',
889 'item_isdeterministic' => '',
890 'item_securitytype_definer' => '',
891 'item_securitytype_invoker' => '',
892 'item_sqldataaccess' => 'NO SQL',
895 return [
897 $data,
898 "<input name='item_type' type='hidden' value='PROCEDURE'",
904 * Test for getExecuteForm
906 * @param array $data Data for routine
907 * @param array $matcher Matcher
909 * @return void
911 * @dataProvider providerGetExecuteForm1
913 public function testGetExecuteForm1($data, $matcher)
915 $this->routines->setGlobals();
916 $GLOBALS['cfg']['ShowFunctionFields'] = true;
918 $this->assertStringContainsString(
919 $matcher,
920 $this->routines->getExecuteForm($data)
925 * Data provider for testGetExecuteForm1
927 * @return array
929 public function providerGetExecuteForm1()
931 $data = [
932 'item_name' => 'foo',
933 'item_returnlength' => '',
934 'item_returnopts_num' => '',
935 'item_returnopts_text' => '',
936 'item_definition' => 'SELECT 1;',
937 'item_comment' => '',
938 'item_definer' => '',
939 'item_type' => 'PROCEDURE',
940 'item_num_params' => 6,
941 'item_param_dir' => [
942 0 => 'IN',
943 1 => 'OUT',
944 2 => 'IN',
945 3 => 'IN',
946 4 => 'IN',
947 5 => 'IN',
949 'item_param_name' => [
950 0 => 'foo',
951 1 => 'foa',
952 2 => 'fob',
953 3 => 'foc',
954 4 => 'fod',
955 5 => 'foe',
957 'item_param_type' => [
958 0 => 'DATE',
959 1 => 'VARCHAR',
960 2 => 'DATETIME',
961 3 => 'GEOMETRY',
962 4 => 'ENUM',
963 5 => 'SET',
965 'item_param_length' => [
966 0 => '',
967 1 => '22',
968 2 => '',
969 3 => '',
970 4 => "'a','b'",
971 5 => "'a','b'",
973 'item_param_length_arr' => [
974 0 => [],
975 1 => ['22'],
976 2 => [],
977 3 => [],
978 4 => [
979 "'a'",
980 "'b'",
982 5 => [
983 "'a'",
984 "'b'",
987 'item_param_opts_num' => [
988 0 => '',
989 1 => '',
990 2 => '',
991 3 => '',
992 4 => '',
993 5 => '',
995 'item_param_opts_text' => [
996 0 => '',
997 1 => 'utf8',
998 2 => '',
999 3 => '',
1000 4 => '',
1001 5 => '',
1003 'item_returntype' => '',
1004 'item_isdeterministic' => '',
1005 'item_securitytype_definer' => '',
1006 'item_securitytype_invoker' => '',
1007 'item_sqldataaccess' => '',
1010 return [
1012 $data,
1013 "name='item_name'",
1016 $data,
1017 "name='funcs[foo]'",
1020 $data,
1021 "<input class='datefield' type='text' name='params[foo]'>",
1024 $data,
1025 "name='funcs[fob]'",
1028 $data,
1029 "<input class='datetimefield' type='text' name='params[fob]'",
1032 $data,
1033 "name='params[fod][]'",
1036 $data,
1037 "name='params[foe][]'",
1040 $data,
1041 "name='execute_routine'",
1047 * Test for getExecuteForm
1049 * @param array $data Data for routine
1050 * @param array $matcher Matcher
1052 * @return void
1054 * @dataProvider providerGetExecuteForm2
1056 public function testGetExecuteForm2($data, $matcher)
1058 Response::getInstance()->setAjax(true);
1059 $this->routines->setGlobals();
1060 $this->assertStringContainsString(
1061 $matcher,
1062 $this->routines->getExecuteForm($data)
1064 Response::getInstance()->setAjax(false);
1068 * Data provider for testGetExecuteForm2
1070 * @return array
1072 public function providerGetExecuteForm2()
1074 $data = [
1075 'item_name' => 'foo',
1076 'item_returnlength' => '',
1077 'item_returnopts_num' => '',
1078 'item_returnopts_text' => '',
1079 'item_definition' => 'SELECT 1;',
1080 'item_comment' => '',
1081 'item_definer' => '',
1082 'item_type' => 'PROCEDURE',
1083 'item_num_params' => 6,
1084 'item_param_dir' => [
1085 0 => 'IN',
1086 1 => 'OUT',
1087 2 => 'IN',
1088 3 => 'IN',
1089 4 => 'IN',
1090 5 => 'IN',
1092 'item_param_name' => [
1093 0 => 'foo',
1094 1 => 'foa',
1095 2 => 'fob',
1096 3 => 'foc',
1097 4 => 'fod',
1098 5 => 'foe',
1100 'item_param_type' => [
1101 0 => 'DATE',
1102 1 => 'VARCHAR',
1103 2 => 'DATETIME',
1104 3 => 'GEOMETRY',
1105 4 => 'ENUM',
1106 5 => 'SET',
1108 'item_param_length' => [
1109 0 => '',
1110 1 => '22',
1111 2 => '',
1112 3 => '',
1113 4 => "'a','b'",
1114 5 => "'a','b'",
1116 'item_param_length_arr' => [
1117 0 => [],
1118 1 => ['22'],
1119 2 => [],
1120 3 => [],
1121 4 => [
1122 "'a'",
1123 "'b'",
1125 5 => [
1126 "'a'",
1127 "'b'",
1130 'item_param_opts_num' => [
1131 0 => '',
1132 1 => '',
1133 2 => '',
1134 3 => '',
1135 4 => '',
1136 5 => '',
1138 'item_param_opts_text' => [
1139 0 => '',
1140 1 => 'utf8',
1141 2 => '',
1142 3 => '',
1143 4 => '',
1144 5 => '',
1146 'item_returntype' => '',
1147 'item_isdeterministic' => '',
1148 'item_securitytype_definer' => '',
1149 'item_securitytype_invoker' => '',
1150 'item_sqldataaccess' => '',
1153 return [
1155 $data,
1156 "name='execute_routine'",
1159 $data,
1160 "name='ajax_request'",
1166 * Test for getQueryFromRequest
1168 * @param array $request Request
1169 * @param string $query Query
1170 * @param int $num_err Error number
1172 * @return void
1174 * @dataProvider providerGetQueryFromRequest
1176 public function testGetQueryFromRequest($request, $query, $num_err): void
1178 global $errors, $cfg;
1180 $cfg['ShowFunctionFields'] = false;
1182 $errors = [];
1183 $this->routines->setGlobals();
1185 $old_dbi = $GLOBALS['dbi'] ?? null;
1186 $dbi = $this->getMockBuilder('PhpMyAdmin\DatabaseInterface')
1187 ->disableOriginalConstructor()
1188 ->getMock();
1189 $dbi->types = new Types($dbi);
1190 $dbi->expects($this->any())
1191 ->method('escapeString')
1192 ->will(
1193 $this->returnValueMap(
1196 'foo',
1197 DatabaseInterface::CONNECT_USER,
1198 'foo',
1201 "foo's bar",
1202 DatabaseInterface::CONNECT_USER,
1203 "foo\'s bar",
1207 DatabaseInterface::CONNECT_USER,
1213 $GLOBALS['dbi'] = $dbi;
1215 $routines = new Routines($dbi);
1217 unset($_POST);
1218 $_POST = $request;
1219 $this->assertEquals($query, $routines->getQueryFromRequest());
1220 $this->assertCount($num_err, $errors);
1222 // reset
1223 $GLOBALS['dbi'] = $old_dbi;
1227 * Data provider for testGetQueryFromRequest
1229 * @return array
1231 public function providerGetQueryFromRequest()
1233 return [
1234 // Testing success
1237 'item_name' => 'p r o c',
1238 'item_returnlength' => '',
1239 'item_returnopts_num' => '',
1240 'item_returnopts_text' => '',
1241 'item_definition' => 'SELECT 0;',
1242 'item_comment' => 'foo',
1243 'item_definer' => 'me@home',
1244 'item_type' => 'PROCEDURE',
1245 'item_num_params' => '0',
1246 'item_param_dir' => '',
1247 'item_param_name' => '',
1248 'item_param_type' => '',
1249 'item_param_length' => '',
1250 'item_param_opts_num' => '',
1251 'item_param_opts_text' => '',
1252 'item_returntype' => '',
1253 'item_isdeterministic' => '',
1254 'item_securitytype' => 'INVOKER',
1255 'item_sqldataaccess' => 'NO SQL',
1257 'CREATE DEFINER=`me`@`home` PROCEDURE `p r o c`() COMMENT \'foo\' '
1258 . 'DETERMINISTIC NO SQL SQL SECURITY INVOKER SELECT 0;',
1263 'item_name' => 'pr``oc',
1264 'item_returnlength' => '',
1265 'item_returnopts_num' => '',
1266 'item_returnopts_text' => '',
1267 'item_definition' => 'SELECT \'foobar\';',
1268 'item_comment' => '',
1269 'item_definer' => 'someuser@somehost',
1270 'item_type' => 'PROCEDURE',
1271 'item_num_params' => '2',
1272 'item_param_dir' => [
1273 'IN',
1274 'INOUT',
1276 'item_param_name' => [
1277 'pa`ram',
1278 'par 2',
1280 'item_param_type' => [
1281 'INT',
1282 'ENUM',
1284 'item_param_length' => [
1285 '10',
1286 '\'a\', \'b\'',
1288 'item_param_opts_num' => [
1289 'ZEROFILL',
1292 'item_param_opts_text' => [
1293 'utf8',
1294 'latin1',
1296 'item_returntype' => '',
1297 'item_securitytype' => 'DEFINER',
1298 'item_sqldataaccess' => 'foobar',
1300 'CREATE DEFINER=`someuser`@`somehost` PROCEDURE `pr````oc`'
1301 . '(IN `pa``ram` INT(10) ZEROFILL, INOUT `par 2` ENUM(\'a\', \'b\')'
1302 . ' CHARSET latin1) NOT DETERMINISTIC SQL SECURITY DEFINER SELECT '
1303 . '\'foobar\';',
1308 'item_name' => 'func\\',
1309 'item_returnlength' => '5,5',
1310 'item_returnopts_num' => 'UNSIGNED ZEROFILL',
1311 'item_returnopts_text' => '',
1312 'item_definition' => 'SELECT \'foobar\';',
1313 'item_comment' => 'foo\'s bar',
1314 'item_definer' => '',
1315 'item_type' => 'FUNCTION',
1316 'item_num_params' => '1',
1317 'item_param_dir' => '',
1318 'item_param_name' => ['pa`ram'],
1319 'item_param_type' => ['VARCHAR'],
1320 'item_param_length' => ['45'],
1321 'item_param_opts_num' => [''],
1322 'item_param_opts_text' => ['latin1'],
1323 'item_returntype' => 'DECIMAL',
1324 'item_isdeterministic' => 'ON',
1325 'item_securitytype' => 'DEFINER',
1326 'item_sqldataaccess' => 'READ SQL DATA',
1328 'CREATE FUNCTION `func\\`(`pa``ram` VARCHAR(45) CHARSET latin1) '
1329 . 'RETURNS DECIMAL(5,5) UNSIGNED ZEROFILL COMMENT \'foo\\\'s bar\' '
1330 . 'DETERMINISTIC SQL SECURITY DEFINER SELECT \'foobar\';',
1335 'item_name' => 'func',
1336 'item_returnlength' => '20',
1337 'item_returnopts_num' => '',
1338 'item_returnopts_text' => 'utf8',
1339 'item_definition' => 'SELECT 0;',
1340 'item_comment' => '',
1341 'item_definer' => '',
1342 'item_type' => 'FUNCTION',
1343 'item_num_params' => '1',
1344 'item_returntype' => 'VARCHAR',
1345 'item_securitytype' => 'DEFINER',
1346 'item_sqldataaccess' => 'READ SQL DATA',
1348 'CREATE FUNCTION `func`() RETURNS VARCHAR(20) CHARSET utf8 NOT '
1349 . 'DETERMINISTIC SQL SECURITY DEFINER SELECT 0;',
1352 // Testing failures
1355 'CREATE () NOT DETERMINISTIC ', // invalid query
1360 'item_name' => 'proc',
1361 'item_returnlength' => '',
1362 'item_returnopts_num' => '',
1363 'item_returnopts_text' => '',
1364 'item_definition' => 'SELECT 0;',
1365 'item_comment' => 'foo',
1366 'item_definer' => 'mehome', // invalid definer format
1367 'item_type' => 'PROCEDURE',
1368 'item_num_params' => '0',
1369 'item_param_dir' => '',
1370 'item_param_name' => '',
1371 'item_param_type' => '',
1372 'item_param_length' => '',
1373 'item_param_opts_num' => '',
1374 'item_param_opts_text' => '',
1375 'item_returntype' => '',
1376 'item_isdeterministic' => '',
1377 'item_securitytype' => 'INVOKER',
1378 'item_sqldataaccess' => 'NO SQL',
1380 'CREATE PROCEDURE `proc`() COMMENT \'foo\' DETERMINISTIC '
1381 . 'NO SQL SQL SECURITY INVOKER SELECT 0;', // valid query
1386 'item_name' => 'proc',
1387 'item_returnlength' => '',
1388 'item_returnopts_num' => '',
1389 'item_returnopts_text' => '',
1390 'item_definition' => 'SELECT 0;',
1391 'item_comment' => '',
1392 'item_definer' => '',
1393 'item_type' => 'PROCEDURE',
1394 'item_num_params' => '2',
1395 'item_param_dir' => [
1396 'FAIL',
1397 'INOUT',
1398 ], // invalid direction
1399 'item_param_name' => [
1400 'pa`ram',
1401 'goo',
1403 'item_param_type' => [
1404 'INT',
1405 'ENUM',
1407 'item_param_length' => [
1408 '10',
1410 ], // missing ENUM values
1411 'item_param_opts_num' => [
1412 'ZEROFILL',
1415 'item_param_opts_text' => [
1416 'utf8',
1417 'latin1',
1419 'item_returntype' => '',
1420 'item_securitytype' => 'DEFINER',
1421 'item_sqldataaccess' => 'foobar', // invalid, will just be ignored without throwing errors
1423 'CREATE PROCEDURE `proc`((10) ZEROFILL, '
1424 . 'INOUT `goo` ENUM CHARSET latin1) NOT DETERMINISTIC '
1425 . 'SQL SECURITY DEFINER SELECT 0;', // invalid query
1430 'item_name' => 'func',
1431 'item_returnlength' => '', // missing length for VARCHAR
1432 'item_returnopts_num' => '',
1433 'item_returnopts_text' => 'utf8',
1434 'item_definition' => 'SELECT 0;',
1435 'item_comment' => '',
1436 'item_definer' => '',
1437 'item_type' => 'FUNCTION',
1438 'item_num_params' => '2',
1439 'item_param_dir' => ['IN'],
1440 'item_param_name' => [''], // missing name
1441 'item_param_type' => ['INT'],
1442 'item_param_length' => ['10'],
1443 'item_param_opts_num' => ['ZEROFILL'],
1444 'item_param_opts_text' => ['latin1'],
1445 'item_returntype' => 'VARCHAR',
1446 'item_securitytype' => 'DEFINER',
1447 'item_sqldataaccess' => '',
1449 'CREATE FUNCTION `func`() RETURNS VARCHAR CHARSET utf8 NOT '
1450 . 'DETERMINISTIC SQL SECURITY DEFINER SELECT 0;', // invalid query
1455 'item_name' => 'func',
1456 'item_returnlength' => '',
1457 'item_returnopts_num' => '',
1458 'item_returnopts_text' => '',
1459 'item_definition' => 'SELECT 0;',
1460 'item_comment' => '',
1461 'item_definer' => '',
1462 'item_type' => 'FUNCTION',
1463 'item_num_params' => '0',
1464 'item_returntype' => 'FAIL', // invalid return type
1465 'item_securitytype' => 'DEFINER',
1466 'item_sqldataaccess' => '',
1468 'CREATE FUNCTION `func`() NOT DETERMINISTIC SQL '
1469 . 'SECURITY DEFINER SELECT 0;', // invalid query