aboutsummaryrefslogtreecommitdiff
path: root/srcs/phpmyadmin/libraries/classes/Plugins/Transformations
diff options
context:
space:
mode:
Diffstat (limited to 'srcs/phpmyadmin/libraries/classes/Plugins/Transformations')
-rw-r--r--srcs/phpmyadmin/libraries/classes/Plugins/Transformations/Abs/Bool2TextTransformationsPlugin.php69
-rw-r--r--srcs/phpmyadmin/libraries/classes/Plugins/Transformations/Abs/CodeMirrorEditorTransformationPlugin.php75
-rw-r--r--srcs/phpmyadmin/libraries/classes/Plugins/Transformations/Abs/DateFormatTransformationsPlugin.php158
-rw-r--r--srcs/phpmyadmin/libraries/classes/Plugins/Transformations/Abs/DownloadTransformationsPlugin.php93
-rw-r--r--srcs/phpmyadmin/libraries/classes/Plugins/Transformations/Abs/ExternalTransformationsPlugin.php160
-rw-r--r--srcs/phpmyadmin/libraries/classes/Plugins/Transformations/Abs/FormattedTransformationsPlugin.php65
-rw-r--r--srcs/phpmyadmin/libraries/classes/Plugins/Transformations/Abs/HexTransformationsPlugin.php71
-rw-r--r--srcs/phpmyadmin/libraries/classes/Plugins/Transformations/Abs/ImageLinkTransformationsPlugin.php63
-rw-r--r--srcs/phpmyadmin/libraries/classes/Plugins/Transformations/Abs/ImageUploadTransformationsPlugin.php121
-rw-r--r--srcs/phpmyadmin/libraries/classes/Plugins/Transformations/Abs/InlineTransformationsPlugin.php78
-rw-r--r--srcs/phpmyadmin/libraries/classes/Plugins/Transformations/Abs/LongToIPv4TransformationsPlugin.php66
-rw-r--r--srcs/phpmyadmin/libraries/classes/Plugins/Transformations/Abs/PreApPendTransformationsPlugin.php68
-rw-r--r--srcs/phpmyadmin/libraries/classes/Plugins/Transformations/Abs/RegexValidationTransformationsPlugin.php74
-rw-r--r--srcs/phpmyadmin/libraries/classes/Plugins/Transformations/Abs/SQLTransformationsPlugin.php62
-rw-r--r--srcs/phpmyadmin/libraries/classes/Plugins/Transformations/Abs/SubstringTransformationsPlugin.php93
-rw-r--r--srcs/phpmyadmin/libraries/classes/Plugins/Transformations/Abs/TextFileUploadTransformationsPlugin.php103
-rw-r--r--srcs/phpmyadmin/libraries/classes/Plugins/Transformations/Abs/TextImageLinkTransformationsPlugin.php75
-rw-r--r--srcs/phpmyadmin/libraries/classes/Plugins/Transformations/Abs/TextLinkTransformationsPlugin.php77
-rw-r--r--srcs/phpmyadmin/libraries/classes/Plugins/Transformations/Input/Image_JPEG_Upload.php44
-rw-r--r--srcs/phpmyadmin/libraries/classes/Plugins/Transformations/Input/Text_Plain_FileUpload.php43
-rw-r--r--srcs/phpmyadmin/libraries/classes/Plugins/Transformations/Input/Text_Plain_Iptobinary.php141
-rw-r--r--srcs/phpmyadmin/libraries/classes/Plugins/Transformations/Input/Text_Plain_JsonEditor.php85
-rw-r--r--srcs/phpmyadmin/libraries/classes/Plugins/Transformations/Input/Text_Plain_RegexValidation.php44
-rw-r--r--srcs/phpmyadmin/libraries/classes/Plugins/Transformations/Input/Text_Plain_SqlEditor.php85
-rw-r--r--srcs/phpmyadmin/libraries/classes/Plugins/Transformations/Input/Text_Plain_XmlEditor.php85
-rw-r--r--srcs/phpmyadmin/libraries/classes/Plugins/Transformations/Output/Application_Octetstream_Download.php43
-rw-r--r--srcs/phpmyadmin/libraries/classes/Plugins/Transformations/Output/Application_Octetstream_Hex.php43
-rw-r--r--srcs/phpmyadmin/libraries/classes/Plugins/Transformations/Output/Image_JPEG_Inline.php43
-rw-r--r--srcs/phpmyadmin/libraries/classes/Plugins/Transformations/Output/Image_JPEG_Link.php43
-rw-r--r--srcs/phpmyadmin/libraries/classes/Plugins/Transformations/Output/Image_PNG_Inline.php43
-rw-r--r--srcs/phpmyadmin/libraries/classes/Plugins/Transformations/Output/Text_Octetstream_Sql.php43
-rw-r--r--srcs/phpmyadmin/libraries/classes/Plugins/Transformations/Output/Text_Plain_Binarytoip.php97
-rw-r--r--srcs/phpmyadmin/libraries/classes/Plugins/Transformations/Output/Text_Plain_Bool2Text.php45
-rw-r--r--srcs/phpmyadmin/libraries/classes/Plugins/Transformations/Output/Text_Plain_Dateformat.php43
-rw-r--r--srcs/phpmyadmin/libraries/classes/Plugins/Transformations/Output/Text_Plain_External.php43
-rw-r--r--srcs/phpmyadmin/libraries/classes/Plugins/Transformations/Output/Text_Plain_Formatted.php43
-rw-r--r--srcs/phpmyadmin/libraries/classes/Plugins/Transformations/Output/Text_Plain_Imagelink.php43
-rw-r--r--srcs/phpmyadmin/libraries/classes/Plugins/Transformations/Output/Text_Plain_Json.php101
-rw-r--r--srcs/phpmyadmin/libraries/classes/Plugins/Transformations/Output/Text_Plain_Sql.php60
-rw-r--r--srcs/phpmyadmin/libraries/classes/Plugins/Transformations/Output/Text_Plain_Xml.php101
-rw-r--r--srcs/phpmyadmin/libraries/classes/Plugins/Transformations/README4
-rw-r--r--srcs/phpmyadmin/libraries/classes/Plugins/Transformations/TEMPLATE45
-rw-r--r--srcs/phpmyadmin/libraries/classes/Plugins/Transformations/TEMPLATE_ABSTRACT73
-rw-r--r--srcs/phpmyadmin/libraries/classes/Plugins/Transformations/Text_Plain_Link.php43
-rw-r--r--srcs/phpmyadmin/libraries/classes/Plugins/Transformations/Text_Plain_Longtoipv4.php43
-rw-r--r--srcs/phpmyadmin/libraries/classes/Plugins/Transformations/Text_Plain_PreApPend.php44
-rw-r--r--srcs/phpmyadmin/libraries/classes/Plugins/Transformations/Text_Plain_Substring.php43
47 files changed, 3227 insertions, 0 deletions
diff --git a/srcs/phpmyadmin/libraries/classes/Plugins/Transformations/Abs/Bool2TextTransformationsPlugin.php b/srcs/phpmyadmin/libraries/classes/Plugins/Transformations/Abs/Bool2TextTransformationsPlugin.php
new file mode 100644
index 0000000..696aa64
--- /dev/null
+++ b/srcs/phpmyadmin/libraries/classes/Plugins/Transformations/Abs/Bool2TextTransformationsPlugin.php
@@ -0,0 +1,69 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Abstract class for the Bool2Text transformations plugins
+ *
+ * @package PhpMyAdmin-Transformations
+ * @subpackage Bool2Text
+ */
+declare(strict_types=1);
+
+namespace PhpMyAdmin\Plugins\Transformations\Abs;
+
+use PhpMyAdmin\Plugins\TransformationsPlugin;
+use stdClass;
+
+/**
+ * Provides common methods for all of the Bool2Text transformations plugins.
+ *
+ * @package PhpMyAdmin-Transformations
+ * @subpackage Bool2Text
+ */
+abstract class Bool2TextTransformationsPlugin extends TransformationsPlugin
+{
+ /**
+ * Gets the transformation description of the specific plugin
+ *
+ * @return string
+ */
+ public static function getInfo()
+ {
+ return __(
+ 'Converts Boolean values to text (default \'T\' and \'F\').'
+ . ' First option is for TRUE, second for FALSE. Nonzero=true.'
+ );
+ }
+
+ /**
+ * Does the actual work of each specific transformations plugin.
+ *
+ * @param string $buffer text to be transformed
+ * @param array $options transformation options
+ * @param stdClass|null $meta meta information
+ *
+ * @return string
+ */
+ public function applyTransformation($buffer, array $options = [], ?stdClass $meta = null)
+ {
+ $cfg = $GLOBALS['cfg'];
+ $options = $this->getOptions($options, $cfg['DefaultTransformations']['Bool2Text']);
+
+ if ($buffer == '0') {
+ return $options[1]; // return false label
+ }
+
+ return $options[0]; // or true one if nonzero
+ }
+
+ /* ~~~~~~~~~~~~~~~~~~~~ Getters and Setters ~~~~~~~~~~~~~~~~~~~~ */
+
+ /**
+ * Gets the transformation name of the specific plugin
+ *
+ * @return string
+ */
+ public static function getName()
+ {
+ return "Bool2Text";
+ }
+}
diff --git a/srcs/phpmyadmin/libraries/classes/Plugins/Transformations/Abs/CodeMirrorEditorTransformationPlugin.php b/srcs/phpmyadmin/libraries/classes/Plugins/Transformations/Abs/CodeMirrorEditorTransformationPlugin.php
new file mode 100644
index 0000000..bbd1fff
--- /dev/null
+++ b/srcs/phpmyadmin/libraries/classes/Plugins/Transformations/Abs/CodeMirrorEditorTransformationPlugin.php
@@ -0,0 +1,75 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Abstract class for syntax highlighted editors using CodeMirror
+ *
+ * @package PhpMyAdmin-Transformations
+ */
+declare(strict_types=1);
+
+namespace PhpMyAdmin\Plugins\Transformations\Abs;
+
+use PhpMyAdmin\Plugins\IOTransformationsPlugin;
+use stdClass;
+
+/**
+ * Provides common methods for all the CodeMirror syntax highlighted editors
+ *
+ * @package PhpMyAdmin-Transformations
+ */
+abstract class CodeMirrorEditorTransformationPlugin extends IOTransformationsPlugin
+{
+ /**
+ * Does the actual work of each specific transformations plugin.
+ *
+ * @param string $buffer text to be transformed
+ * @param array $options transformation options
+ * @param stdClass|null $meta meta information
+ *
+ * @return string
+ */
+ public function applyTransformation($buffer, array $options = [], ?stdClass $meta = null)
+ {
+ return $buffer;
+ }
+
+ /**
+ * Returns the html for input field to override default textarea.
+ * Note: Return empty string if default textarea is required.
+ *
+ * @param array $column column details
+ * @param int $row_id row number
+ * @param string $column_name_appendix the name attribute
+ * @param array $options transformation options
+ * @param string $value Current field value
+ * @param string $text_dir text direction
+ * @param int $tabindex tab index
+ * @param int $tabindex_for_value offset for the values tabindex
+ * @param int $idindex id index
+ *
+ * @return string the html for input field
+ */
+ public function getInputHtml(
+ array $column,
+ $row_id,
+ $column_name_appendix,
+ array $options,
+ $value,
+ $text_dir,
+ $tabindex,
+ $tabindex_for_value,
+ $idindex
+ ) {
+ $html = '';
+ if (! empty($value)) {
+ $html = '<input type="hidden" name="fields_prev' . $column_name_appendix
+ . '" value="' . htmlspecialchars($value) . '">';
+ }
+ $class = 'transform_' . strtolower(static::getName()) . '_editor';
+ $html .= '<textarea name="fields' . $column_name_appendix . '"'
+ . ' dir="' . $text_dir . '" class="' . $class . '">'
+ . htmlspecialchars($value) . '</textarea>';
+
+ return $html;
+ }
+}
diff --git a/srcs/phpmyadmin/libraries/classes/Plugins/Transformations/Abs/DateFormatTransformationsPlugin.php b/srcs/phpmyadmin/libraries/classes/Plugins/Transformations/Abs/DateFormatTransformationsPlugin.php
new file mode 100644
index 0000000..32ed494
--- /dev/null
+++ b/srcs/phpmyadmin/libraries/classes/Plugins/Transformations/Abs/DateFormatTransformationsPlugin.php
@@ -0,0 +1,158 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Abstract class for the date format transformations plugins
+ *
+ * @package PhpMyAdmin-Transformations
+ * @subpackage DateFormat
+ */
+declare(strict_types=1);
+
+namespace PhpMyAdmin\Plugins\Transformations\Abs;
+
+use PhpMyAdmin\Plugins\TransformationsPlugin;
+use PhpMyAdmin\Sanitize;
+use PhpMyAdmin\Util;
+use stdClass;
+
+/**
+ * Provides common methods for all of the date format transformations plugins.
+ *
+ * @package PhpMyAdmin
+ */
+abstract class DateFormatTransformationsPlugin extends TransformationsPlugin
+{
+ /**
+ * Gets the transformation description of the specific plugin
+ *
+ * @return string
+ */
+ public static function getInfo()
+ {
+ return __(
+ 'Displays a TIME, TIMESTAMP, DATETIME or numeric unix timestamp'
+ . ' column as formatted date. The first option is the offset (in'
+ . ' hours) which will be added to the timestamp (Default: 0). Use'
+ . ' second option to specify a different date/time format string.'
+ . ' Third option determines whether you want to see local date or'
+ . ' UTC one (use "local" or "utc" strings) for that. According to'
+ . ' that, date format has different value - for "local" see the'
+ . ' documentation for PHP\'s strftime() function and for "utc" it'
+ . ' is done using gmdate() function.'
+ );
+ }
+
+ /**
+ * Does the actual work of each specific transformations plugin.
+ *
+ * @param string $buffer text to be transformed
+ * @param array $options transformation options
+ * @param stdClass|null $meta meta information
+ *
+ * @return string
+ */
+ public function applyTransformation($buffer, array $options = [], ?stdClass $meta = null)
+ {
+ $buffer = (string) $buffer;
+ // possibly use a global transform and feed it with special options
+ $cfg = $GLOBALS['cfg'];
+ $options = $this->getOptions($options, $cfg['DefaultTransformations']['DateFormat']);
+
+ // further operations on $buffer using the $options[] array.
+ $options[2] = mb_strtolower($options[2]);
+
+ if (empty($options[1])) {
+ if ($options[2] == 'local') {
+ $options[1] = __('%B %d, %Y at %I:%M %p');
+ } else {
+ $options[1] = 'Y-m-d H:i:s';
+ }
+ }
+
+ $timestamp = -1;
+
+ // INT columns will be treated as UNIX timestamps
+ // and need to be detected before the verification for
+ // MySQL TIMESTAMP
+ if ($meta->type == 'int') {
+ $timestamp = $buffer;
+
+ // Detect TIMESTAMP(6 | 8 | 10 | 12 | 14)
+ // TIMESTAMP (2 | 4) not supported here.
+ // (Note: prior to MySQL 4.1, TIMESTAMP has a display size
+ // for example TIMESTAMP(8) means YYYYMMDD)
+ } else {
+ if (preg_match('/^(\d{2}){3,7}$/', $buffer)) {
+ if (mb_strlen($buffer) == 14 || mb_strlen($buffer) == 8) {
+ $offset = 4;
+ } else {
+ $offset = 2;
+ }
+
+ $aDate = [];
+ $aDate['year'] = (int) mb_substr($buffer, 0, $offset);
+ $aDate['month'] = (int) mb_substr($buffer, $offset, 2);
+ $aDate['day'] = (int) mb_substr($buffer, $offset + 2, 2);
+ $aDate['hour'] = (int) mb_substr($buffer, $offset + 4, 2);
+ $aDate['minute'] = (int) mb_substr($buffer, $offset + 6, 2);
+ $aDate['second'] = (int) mb_substr($buffer, $offset + 8, 2);
+
+ if (checkdate($aDate['month'], $aDate['day'], $aDate['year'])) {
+ $timestamp = mktime(
+ $aDate['hour'],
+ $aDate['minute'],
+ $aDate['second'],
+ $aDate['month'],
+ $aDate['day'],
+ $aDate['year']
+ );
+ }
+ // If all fails, assume one of the dozens of valid strtime() syntaxes
+ // (https://www.gnu.org/manual/tar-1.12/html_chapter/tar_7.html)
+ } else {
+ if (preg_match('/^[0-9]\d{1,9}$/', $buffer)) {
+ $timestamp = (int) $buffer;
+ } else {
+ $timestamp = strtotime($buffer);
+ }
+ }
+ }
+
+ // If all above failed, maybe it's a Unix timestamp already?
+ if ($timestamp < 0 && preg_match('/^[1-9]\d{1,9}$/', $buffer)) {
+ $timestamp = $buffer;
+ }
+
+ // Reformat a valid timestamp
+ if ($timestamp >= 0) {
+ $timestamp -= (int) $options[0] * 60 * 60;
+ $source = $buffer;
+ if ($options[2] == 'local') {
+ $text = Util::localisedDate(
+ $timestamp,
+ $options[1]
+ );
+ } elseif ($options[2] == 'utc') {
+ $text = gmdate($options[1], $timestamp);
+ } else {
+ $text = 'INVALID DATE TYPE';
+ }
+ return '<dfn onclick="alert(\'' . Sanitize::jsFormat($source, false) . '\');" title="'
+ . htmlspecialchars((string) $source) . '">' . htmlspecialchars((string) $text) . '</dfn>';
+ }
+
+ return htmlspecialchars((string) $buffer);
+ }
+
+ /* ~~~~~~~~~~~~~~~~~~~~ Getters and Setters ~~~~~~~~~~~~~~~~~~~~ */
+
+ /**
+ * Gets the transformation name of the specific plugin
+ *
+ * @return string
+ */
+ public static function getName()
+ {
+ return "Date Format";
+ }
+}
diff --git a/srcs/phpmyadmin/libraries/classes/Plugins/Transformations/Abs/DownloadTransformationsPlugin.php b/srcs/phpmyadmin/libraries/classes/Plugins/Transformations/Abs/DownloadTransformationsPlugin.php
new file mode 100644
index 0000000..d6c21d6
--- /dev/null
+++ b/srcs/phpmyadmin/libraries/classes/Plugins/Transformations/Abs/DownloadTransformationsPlugin.php
@@ -0,0 +1,93 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Abstract class for the download transformations plugins
+ *
+ * @package PhpMyAdmin-Transformations
+ * @subpackage Download
+ */
+declare(strict_types=1);
+
+namespace PhpMyAdmin\Plugins\Transformations\Abs;
+
+use PhpMyAdmin\Plugins\TransformationsPlugin;
+use stdClass;
+
+/**
+ * Provides common methods for all of the download transformations plugins.
+ *
+ * @package PhpMyAdmin
+ */
+abstract class DownloadTransformationsPlugin extends TransformationsPlugin
+{
+ /**
+ * Gets the transformation description of the specific plugin
+ *
+ * @return string
+ */
+ public static function getInfo()
+ {
+ return __(
+ 'Displays a link to download the binary data of the column. You can'
+ . ' use the first option to specify the filename, or use the second'
+ . ' option as the name of a column which contains the filename. If'
+ . ' you use the second option, you need to set the first option to'
+ . ' the empty string.'
+ );
+ }
+
+ /**
+ * Does the actual work of each specific transformations plugin.
+ *
+ * @param string $buffer text to be transformed
+ * @param array $options transformation options
+ * @param stdClass|null $meta meta information
+ *
+ * @return string
+ */
+ public function applyTransformation($buffer, array $options = [], ?stdClass $meta = null)
+ {
+ global $row, $fields_meta;
+
+ if (isset($options[0]) && ! empty($options[0])) {
+ $cn = $options[0]; // filename
+ } else {
+ if (isset($options[1]) && ! empty($options[1])) {
+ foreach ($fields_meta as $key => $val) {
+ if ($val->name == $options[1]) {
+ $pos = $key;
+ break;
+ }
+ }
+ if (isset($pos)) {
+ $cn = $row[$pos];
+ }
+ }
+ if (empty($cn)) {
+ $cn = 'binary_file.dat';
+ }
+ }
+
+ return sprintf(
+ '<a href="transformation_wrapper.php%s&amp;ct=application'
+ . '/octet-stream&amp;cn=%s" title="%s" class="disableAjax">%s</a>',
+ $options['wrapper_link'],
+ htmlspecialchars(urlencode($cn)),
+ htmlspecialchars($cn),
+ htmlspecialchars($cn)
+ );
+ }
+
+
+ /* ~~~~~~~~~~~~~~~~~~~~ Getters and Setters ~~~~~~~~~~~~~~~~~~~~ */
+
+ /**
+ * Gets the transformation name of the specific plugin
+ *
+ * @return string
+ */
+ public static function getName()
+ {
+ return "Download";
+ }
+}
diff --git a/srcs/phpmyadmin/libraries/classes/Plugins/Transformations/Abs/ExternalTransformationsPlugin.php b/srcs/phpmyadmin/libraries/classes/Plugins/Transformations/Abs/ExternalTransformationsPlugin.php
new file mode 100644
index 0000000..006ee86
--- /dev/null
+++ b/srcs/phpmyadmin/libraries/classes/Plugins/Transformations/Abs/ExternalTransformationsPlugin.php
@@ -0,0 +1,160 @@
+<?php
+/* vim: set expandtab sw=4 ts=4 sts=4: */
+/**
+ * Abstract class for the external transformations plugins
+ *
+ * @package PhpMyAdmin-Transformations
+ * @subpackage External
+ */
+declare(strict_types=1);
+
+namespace PhpMyAdmin\Plugins\Transformations\Abs;
+
+use PhpMyAdmin\Plugins\TransformationsPlugin;
+use stdClass;
+
+/**
+ * Provides common methods for all of the external transformations plugins.
+ *
+ * @package PhpMyAdmin
+ */
+abstract class ExternalTransformationsPlugin extends TransformationsPlugin
+{
+ /**
+ * Gets the transformation description of the specific plugin
+ *
+ * @return string
+ */
+ public static function getInfo()
+ {
+ return __(
+ 'LINUX ONLY: Launches an external application and feeds it the column'
+ . ' data via standard input. Returns the standard output of the'
+ . ' application. The default is Tidy, to pretty-print HTML code.'
+ . ' For security reasons, you have to manually edit the file'
+ . ' libraries/classes/Plugins/Transformations/Output/Text_Plain_External'
+ . '.php and list the tools you want to make available.'
+ . ' The first option is then the number of the program you want to'
+ . ' use and the second option is the parameters for the program.'
+ . ' The third option, if set to 1, will convert the output using'
+ . ' htmlspecialchars() (Default 1). The fourth option, if set to 1,'
+ . ' will prevent wrapping and ensure that the output appears all on'
+ . ' one line (Default 1).'
+ );
+ }
+
+ /**
+ * Enables no-wrapping
+ *
+ * @param array $options transformation options
+ *
+ * @return bool
+ */
+ public function applyTransformationNoWrap(array $options = [])
+ {
+ if (! isset($options[3]) || $options[3] == '') {
+ $nowrap = true;
+ } elseif ($options[3] == '1' || $options[3] == 1) {
+ $nowrap = true;
+ } else {
+ $nowrap = false;
+ }
+
+ return $nowrap;
+ }
+
+ /**
+ * Does the actual work of each specific transformations plugin.
+ *
+ * @param string $buffer text to be transformed
+ * @param array $options transformation options
+ * @param stdClass|null $meta meta information
+ *
+ * @return string
+ */
+ public function applyTransformation($buffer, array $options = [], ?stdClass $meta = null)
+ {
+ // possibly use a global transform and feed it with special options
+
+ // further operations on $buffer using the $options[] array.
+
+ $allowed_programs = [];
+
+ //
+ // WARNING:
+ //
+ // It's up to administrator to allow anything here. Note that users may
+ // specify any parameters, so when programs allow output redirection or
+ // any other possibly dangerous operations, you should write wrapper
+ // script that will publish only functions you really want.
+ //
+ // Add here program definitions like (note that these are NOT safe
+ // programs):
+ //
+ //$allowed_programs[0] = '/usr/local/bin/tidy';
+ //$allowed_programs[1] = '/usr/local/bin/validate';
+
+ // no-op when no allowed programs
+ if (count($allowed_programs) === 0) {
+ return $buffer;
+ }
+
+ $cfg = $GLOBALS['cfg'];
+ $options = $this->getOptions(
+ $options,
+ $cfg['DefaultTransformations']['External']
+ );
+
+ if (isset($allowed_programs[$options[0]])) {
+ $program = $allowed_programs[$options[0]];
+ } else {
+ $program = $allowed_programs[0];
+ }
+
+ // needs PHP >= 4.3.0
+ $newstring = '';
+ $descriptorspec = [
+