ExternalTransformationsPlugin.php 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. <?php
  2. /* vim: set expandtab sw=4 ts=4 sts=4: */
  3. /**
  4. * Abstract class for the external transformations plugins
  5. *
  6. * @package PhpMyAdmin-Transformations
  7. * @subpackage External
  8. */
  9. declare(strict_types=1);
  10. namespace PhpMyAdmin\Plugins\Transformations\Abs;
  11. use PhpMyAdmin\Plugins\TransformationsPlugin;
  12. use stdClass;
  13. /**
  14. * Provides common methods for all of the external transformations plugins.
  15. *
  16. * @package PhpMyAdmin
  17. */
  18. abstract class ExternalTransformationsPlugin extends TransformationsPlugin
  19. {
  20. /**
  21. * Gets the transformation description of the specific plugin
  22. *
  23. * @return string
  24. */
  25. public static function getInfo()
  26. {
  27. return __(
  28. 'LINUX ONLY: Launches an external application and feeds it the column'
  29. . ' data via standard input. Returns the standard output of the'
  30. . ' application. The default is Tidy, to pretty-print HTML code.'
  31. . ' For security reasons, you have to manually edit the file'
  32. . ' libraries/classes/Plugins/Transformations/Abs/ExternalTransformationsPlugin.php'
  33. . ' and list the tools you want to make available.'
  34. . ' The first option is then the number of the program you want to'
  35. . ' use. The second option should be blank for historical reasons.'
  36. . ' The third option, if set to 1, will convert the output using'
  37. . ' htmlspecialchars() (Default 1). The fourth option, if set to 1,'
  38. . ' will prevent wrapping and ensure that the output appears all on'
  39. . ' one line (Default 1).'
  40. );
  41. }
  42. /**
  43. * Enables no-wrapping
  44. *
  45. * @param array $options transformation options
  46. *
  47. * @return bool
  48. */
  49. public function applyTransformationNoWrap(array $options = [])
  50. {
  51. if (! isset($options[3]) || $options[3] == '') {
  52. $nowrap = true;
  53. } elseif ($options[3] == '1' || $options[3] == 1) {
  54. $nowrap = true;
  55. } else {
  56. $nowrap = false;
  57. }
  58. return $nowrap;
  59. }
  60. /**
  61. * Does the actual work of each specific transformations plugin.
  62. *
  63. * @param string $buffer text to be transformed
  64. * @param array $options transformation options
  65. * @param stdClass|null $meta meta information
  66. *
  67. * @return string
  68. */
  69. public function applyTransformation($buffer, array $options = [], ?stdClass $meta = null)
  70. {
  71. // possibly use a global transform and feed it with special options
  72. // further operations on $buffer using the $options[] array.
  73. $allowed_programs = [];
  74. //
  75. // WARNING:
  76. //
  77. // It's up to administrator to allow anything here. Note that users may
  78. // specify any parameters, so when programs allow output redirection or
  79. // any other possibly dangerous operations, you should write wrapper
  80. // script that will publish only functions you really want.
  81. //
  82. // Add here program definitions like (note that these are NOT safe
  83. // programs):
  84. //
  85. //$allowed_programs[0] = '/usr/local/bin/tidy';
  86. //$allowed_programs[1] = '/usr/local/bin/validate';
  87. // no-op when no allowed programs
  88. if (count($allowed_programs) === 0) {
  89. return $buffer;
  90. }
  91. $cfg = $GLOBALS['cfg'];
  92. $options = $this->getOptions(
  93. $options,
  94. $cfg['DefaultTransformations']['External']
  95. );
  96. if (isset($allowed_programs[$options[0]])) {
  97. $program = $allowed_programs[$options[0]];
  98. } else {
  99. $program = $allowed_programs[0];
  100. }
  101. if (isset($options[1]) && strlen((string) $options[1]) > 0) {
  102. trigger_error(sprintf(
  103. __(
  104. 'You are using the external transformation command line options field, which has been deprecated for security reasons. '
  105. . 'Add all command line options directly to the definition in %s.'
  106. ),
  107. '[code]libraries/classes/Plugins/Transformations/Abs/ExternalTransformationsPlugin.php[/code]'
  108. ), E_USER_DEPRECATED);
  109. }
  110. // needs PHP >= 4.3.0
  111. $newstring = '';
  112. $descriptorspec = [
  113. 0 => [
  114. "pipe",
  115. "r",
  116. ],
  117. 1 => [
  118. "pipe",
  119. "w",
  120. ],
  121. ];
  122. $process = proc_open($program . ' ' . $options[1], $descriptorspec, $pipes);
  123. if (is_resource($process)) {
  124. fwrite($pipes[0], $buffer);
  125. fclose($pipes[0]);
  126. while (! feof($pipes[1])) {
  127. $newstring .= fgets($pipes[1], 1024);
  128. }
  129. fclose($pipes[1]);
  130. // we don't currently use the return value
  131. proc_close($process);
  132. }
  133. if ($options[2] == 1 || $options[2] == '2') {
  134. $retstring = htmlspecialchars($newstring);
  135. } else {
  136. $retstring = $newstring;
  137. }
  138. return $retstring;
  139. }
  140. /* ~~~~~~~~~~~~~~~~~~~~ Getters and Setters ~~~~~~~~~~~~~~~~~~~~ */
  141. /**
  142. * Gets the transformation name of the specific plugin
  143. *
  144. * @return string
  145. */
  146. public static function getName()
  147. {
  148. return "External";
  149. }
  150. }