Merge branch 'QA_5_2'
Signed-off-by: Maurício Meneghini Fauth <mauricio@mfauth.net>
This commit is contained in:
commit
43640af9f4
25
.github/.readthedocs.yaml
vendored
Normal file
25
.github/.readthedocs.yaml
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
# Read the Docs configuration file for Sphinx projects
|
||||
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
|
||||
|
||||
# Required
|
||||
version: 2
|
||||
|
||||
build:
|
||||
os: ubuntu-24.04
|
||||
tools:
|
||||
python: "3.12"
|
||||
jobs:
|
||||
post_create_environment:
|
||||
- python -m pip install sphinx-rtd-theme
|
||||
|
||||
# Build documentation in the "doc/" directory with Sphinx
|
||||
sphinx:
|
||||
configuration: doc/conf.py
|
||||
# Fail on all warnings to avoid broken references
|
||||
# fail_on_warning: true
|
||||
|
||||
# Optionally build your docs in additional formats such as PDF and ePub
|
||||
formats:
|
||||
- pdf
|
||||
- epub
|
||||
- htmlzip
|
||||
6
.github/workflows/tests.yml
vendored
6
.github/workflows/tests.yml
vendored
@ -63,15 +63,15 @@ jobs:
|
||||
test-php:
|
||||
name: Test on PHP ${{ matrix.php-version }}, ${{ matrix.composer-dependency }} and ${{ matrix.os }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
continue-on-error: ${{ matrix.php-version == '8.4' }}
|
||||
continue-on-error: ${{ matrix.php-version == '8.5' }}
|
||||
strategy:
|
||||
matrix:
|
||||
php-version: ['8.2', '8.3']
|
||||
php-version: ['8.2', '8.3', '8.4']
|
||||
os: [ubuntu-latest]
|
||||
composer-dependency: [locked, highest]
|
||||
php-extensions: ['mbstring, iconv, mysqli, zip, gd, bz2']
|
||||
include:
|
||||
- php-version: '8.4'
|
||||
- php-version: '8.5'
|
||||
os: ubuntu-latest
|
||||
composer-dependency: locked
|
||||
composer-options: '--ignore-platform-req=php+'
|
||||
|
||||
12
docs/conf.py
12
docs/conf.py
@ -44,7 +44,7 @@ master_doc = 'index'
|
||||
|
||||
# General information about the project.
|
||||
project = u'phpMyAdmin'
|
||||
copyright = u'2012 - 2023, The phpMyAdmin devel team'
|
||||
copyright = u'2012 - 2024, The phpMyAdmin devel team'
|
||||
|
||||
# The version info for the project you're documenting, acts as replacement for
|
||||
# |version| and |release|, also used in various other places throughout the
|
||||
@ -100,6 +100,16 @@ pygments_style = 'sphinx'
|
||||
# a list of builtin themes.
|
||||
html_theme = 'default'
|
||||
|
||||
# See: https://docs.readthedocs.io/en/stable/reference/environment-variables.html#envvar-READTHEDOCS
|
||||
on_rtd = os.environ.get('READTHEDOCS', None) == 'True'
|
||||
|
||||
if on_rtd: # only import and set the theme if we're building docs on readthedocs
|
||||
try:
|
||||
import sphinx_rtd_theme
|
||||
html_theme = 'sphinx_rtd_theme'
|
||||
except:
|
||||
html_theme = 'default'
|
||||
|
||||
# Theme options are theme-specific and customize the look and feel of a theme
|
||||
# further. For a list of options available for each theme, see the
|
||||
# documentation.
|
||||
|
||||
@ -8529,7 +8529,7 @@ parameters:
|
||||
-
|
||||
message: '#^Argument of an invalid type mixed supplied for foreach, only iterables are supported\.$#'
|
||||
identifier: foreach.nonIterable
|
||||
count: 2
|
||||
count: 1
|
||||
path: src/Error/ErrorReport.php
|
||||
|
||||
-
|
||||
|
||||
@ -5281,6 +5281,7 @@
|
||||
<code><![CDATA[$line]]></code>
|
||||
</MixedArgument>
|
||||
<MixedArrayAccess>
|
||||
<code><![CDATA[$level['context']]]></code>
|
||||
<code><![CDATA[$level['context']]]></code>
|
||||
<code><![CDATA[$level['url']]]></code>
|
||||
<code><![CDATA[$level['url']]]></code>
|
||||
|
||||
@ -5,7 +5,7 @@ import { Navigation } from './modules/navigation.ts';
|
||||
import { CommonParams } from './modules/common.ts';
|
||||
import highlightSql from './modules/sql-highlight.ts';
|
||||
import { ajaxRemoveMessage, ajaxShowMessage } from './modules/ajax-message.ts';
|
||||
import { escapeHtml } from './modules/functions/escape.ts';
|
||||
import { escapeBacktick, escapeHtml } from './modules/functions/escape.ts';
|
||||
import refreshMainContent from './modules/functions/refreshMainContent.ts';
|
||||
import isStorageSupported from './modules/functions/isStorageSupported.ts';
|
||||
|
||||
@ -320,7 +320,7 @@ const insertQuery = function (queryType) {
|
||||
// @ts-ignore
|
||||
var myListBox = document.sqlform.dummy;
|
||||
// @ts-ignore
|
||||
table = document.sqlform.table.value;
|
||||
table = escapeBacktick(document.sqlform.table.value);
|
||||
|
||||
if (myListBox.options.length > 0) {
|
||||
sqlBoxLocked = true;
|
||||
|
||||
@ -387,7 +387,7 @@ class SvgVisualization extends GisVisualization {
|
||||
$('#tooltip').remove();
|
||||
|
||||
const target = event.target as SVGElement;
|
||||
const contents = target.getAttribute('name').trim();
|
||||
const contents = target.getAttribute('data-label').trim();
|
||||
if (contents === '') {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -55,7 +55,7 @@
|
||||
{% elseif (longtext_double_textarea and 'longtext' in column.pmaType) or 'json' in column.pmaType or 'text' in column.pmaType %}
|
||||
{{ backup_field|raw }}
|
||||
<textarea name="fields[multi_edit][{{ row_id }}][{{ column.md5 }}]" id="field_{{ id_index }}_3" data-type="{{ data_type }}" dir="{{ pma.text_dir }}" rows="{{ textarea_rows }}" cols="{{ textarea_cols }}" tabindex="{{ id_index }}"
|
||||
{{- max_length ? ' data-maxlength="' ~ max_length ~ '"' }}{{ column.isChar ? ' class="char charField"' }} onchange="return verificationsAfterFieldChange('{{ column.md5|escape('js') }}', '{{ row_id|escape('js') }}', '{{ column.pmaType }}')">
|
||||
{{- max_length ? ' data-maxlength="' ~ max_length ~ '"' }}{{ column.isChar ? ' class="charField"' }} onchange="return verificationsAfterFieldChange('{{ column.md5|escape('js') }}', '{{ row_id|escape('js') }}', '{{ column.pmaType }}')">
|
||||
{#- We need to duplicate the first \n or otherwise we will lose the first newline entered in a VARCHAR or TEXT column -#}
|
||||
{{- special_chars starts with "\r\n" ? "\n" }}{{ special_chars|raw -}}
|
||||
</textarea>
|
||||
@ -98,7 +98,7 @@
|
||||
{{ backup_field|raw }}
|
||||
<input type="hidden" name="fields_type[multi_edit][{{ row_id }}][{{ column.md5 }}]" value="hex">
|
||||
<textarea name="fields[multi_edit][{{ row_id }}][{{ column.md5 }}]" id="field_{{ id_index }}_3" data-type="HEX" dir="{{ pma.text_dir }}" rows="{{ textarea_rows }}" cols="{{ textarea_cols }}" tabindex="{{ id_index }}"
|
||||
{{- max_length ? ' data-maxlength="' ~ max_length ~ '"' }}{{ column.isChar ? ' class="char charField"' }} onchange="return verificationsAfterFieldChange('{{ column.md5|escape('js') }}', '{{ row_id|escape('js') }}', '{{ column.pmaType }}')">
|
||||
{{- max_length ? ' data-maxlength="' ~ max_length ~ '"' }}{{ column.isChar ? ' class="charField"' }} onchange="return verificationsAfterFieldChange('{{ column.md5|escape('js') }}', '{{ row_id|escape('js') }}', '{{ column.pmaType }}')">
|
||||
{#- We need to duplicate the first \n or otherwise we will lose the first newline entered in a VARCHAR or TEXT column -#}
|
||||
{{- special_chars starts with "\r\n" ? "\n" }}{{ special_chars|raw -}}
|
||||
</textarea>
|
||||
|
||||
@ -226,12 +226,14 @@ class ErrorReport
|
||||
private function translateStacktrace(array $stack): array
|
||||
{
|
||||
foreach ($stack as &$level) {
|
||||
foreach ($level['context'] as &$line) {
|
||||
if (mb_strlen($line) <= 80) {
|
||||
continue;
|
||||
}
|
||||
if (is_array($level['context'])) {
|
||||
foreach ($level['context'] as &$line) {
|
||||
if (mb_strlen($line) <= 80) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$line = mb_substr($line, 0, 75) . '//...';
|
||||
$line = mb_substr($line, 0, 75) . '//...';
|
||||
}
|
||||
}
|
||||
|
||||
[$uri, $scriptName] = $this->sanitizeUrl($level['url']);
|
||||
|
||||
@ -167,7 +167,7 @@ class GisLineString extends GisGeometry
|
||||
public function prepareRowAsSvg(string $spatial, string $label, array $color, ScaleData $scaleData): string
|
||||
{
|
||||
$lineOptions = [
|
||||
'name' => $label,
|
||||
'data-label' => $label,
|
||||
'id' => $label . $this->getRandomId(),
|
||||
'class' => 'linestring vector',
|
||||
'fill' => 'none',
|
||||
|
||||
@ -188,7 +188,7 @@ class GisMultiLineString extends GisGeometry
|
||||
public function prepareRowAsSvg(string $spatial, string $label, array $color, ScaleData $scaleData): string
|
||||
{
|
||||
$lineOptions = [
|
||||
'name' => $label,
|
||||
'data-label' => $label,
|
||||
'class' => 'linestring vector',
|
||||
'fill' => 'none',
|
||||
'stroke' => sprintf('#%02x%02x%02x', ...$color),
|
||||
|
||||
@ -169,7 +169,7 @@ class GisMultiPoint extends GisGeometry
|
||||
public function prepareRowAsSvg(string $spatial, string $label, array $color, ScaleData $scaleData): string
|
||||
{
|
||||
$pointOptions = [
|
||||
'name' => $label,
|
||||
'data-label' => $label,
|
||||
'class' => 'multipoint vector',
|
||||
'fill' => 'white',
|
||||
'stroke' => sprintf('#%02x%02x%02x', ...$color),
|
||||
|
||||
@ -194,7 +194,7 @@ class GisMultiPolygon extends GisGeometry
|
||||
public function prepareRowAsSvg(string $spatial, string $label, array $color, ScaleData $scaleData): string
|
||||
{
|
||||
$polygonOptions = [
|
||||
'name' => $label,
|
||||
'data-label' => $label,
|
||||
'class' => 'multipolygon vector',
|
||||
'stroke' => 'black',
|
||||
'stroke-width' => 0.5,
|
||||
|
||||
@ -160,7 +160,7 @@ class GisPoint extends GisGeometry
|
||||
public function prepareRowAsSvg(string $spatial, string $label, array $color, ScaleData $scaleData): string
|
||||
{
|
||||
$pointOptions = [
|
||||
'name' => $label,
|
||||
'data-label' => $label,
|
||||
'id' => $label . $this->getRandomId(),
|
||||
'class' => 'point vector',
|
||||
'fill' => 'white',
|
||||
|
||||
@ -163,7 +163,7 @@ class GisPolygon extends GisGeometry
|
||||
public function prepareRowAsSvg(string $spatial, string $label, array $color, ScaleData $scaleData): string
|
||||
{
|
||||
$polygonOptions = [
|
||||
'name' => $label,
|
||||
'data-label' => $label,
|
||||
'id' => $label . $this->getRandomId(),
|
||||
'class' => 'polygon vector',
|
||||
'stroke' => 'black',
|
||||
|
||||
@ -19,6 +19,7 @@ use TCPDF;
|
||||
|
||||
use function assert;
|
||||
use function count;
|
||||
use function htmlspecialchars;
|
||||
use function is_string;
|
||||
use function max;
|
||||
use function mb_strlen;
|
||||
@ -508,7 +509,7 @@ class GisVisualization
|
||||
$label = trim((string) ($row[$this->labelColumn] ?? ''));
|
||||
|
||||
if ($format === 'svg') {
|
||||
$svg .= $gisObj->prepareRowAsSvg($wkt, $label, $color, $scaleData);
|
||||
$svg .= $gisObj->prepareRowAsSvg($wkt, htmlspecialchars($label), $color, $scaleData);
|
||||
} elseif ($format === 'png') {
|
||||
assert($renderer instanceof ImageWrapper);
|
||||
$gisObj->prepareRowAsPng($wkt, $label, $color, $scaleData, $renderer);
|
||||
|
||||
@ -387,7 +387,7 @@ class InsertEdit
|
||||
* @todo clarify the meaning of the "textfield" class and explain
|
||||
* why character columns have the "char" class instead
|
||||
*/
|
||||
$theClass = 'char charField';
|
||||
$theClass = 'charField';
|
||||
$textAreaRows = $this->config->settings['CharTextareaRows'];
|
||||
$textareaCols = $this->config->settings['CharTextareaCols'];
|
||||
$extractedColumnspec = Util::extractColumnSpec($column->type);
|
||||
|
||||
@ -380,7 +380,7 @@ class GisGeometryCollectionTest extends GisGeomTestCase
|
||||
[176, 46, 224],
|
||||
new ScaleData(offsetX: 12, offsetY: 69, scale: 2, height: 150),
|
||||
'<path d=" M 46, 268 L -4, 248 L 6, 208 L 66, 198 Z M 16,'
|
||||
. ' 228 L 46, 224 L 36, 248 Z " name="svg" id="svg1234567890'
|
||||
. ' 228 L 46, 224 L 36, 248 Z " data-label="svg" id="svg1234567890'
|
||||
. '" class="polygon vector" stroke="black" stroke-width="0.5"'
|
||||
. ' fill="#b02ee0" fill-rule="evenodd" fill-opacity="0.8"/>',
|
||||
],
|
||||
|
||||
@ -251,7 +251,7 @@ class GisLineStringTest extends GisGeomTestCase
|
||||
[176, 46, 224],
|
||||
new ScaleData(offsetX: 12, offsetY: 69, scale: 2, height: 150),
|
||||
'<polyline points="0,218 72,138 114,242 26,198 4,182 46,132 " '
|
||||
. 'name="svg" id="svg1234567890" class="linestring vector" fill="none" '
|
||||
. 'data-label="svg" id="svg1234567890" class="linestring vector" fill="none" '
|
||||
. 'stroke="#b02ee0" stroke-width="2"/>',
|
||||
],
|
||||
];
|
||||
|
||||
@ -258,10 +258,10 @@ class GisMultiLineStringTest extends GisGeomTestCase
|
||||
'svg',
|
||||
[176, 46, 224],
|
||||
new ScaleData(offsetX: 12, offsetY: 69, scale: 2, height: 150),
|
||||
'<polyline points="48,260 70,242 100,138 " name="svg" '
|
||||
'<polyline points="48,260 70,242 100,138 " data-label="svg" '
|
||||
. 'class="linestring vector" fill="none" stroke="#b02ee0" '
|
||||
. 'stroke-width="2" id="svg1234567890"/><polyline points="48,268 10,'
|
||||
. '242 332,182 " name="svg" class="linestring vector" fill="none" '
|
||||
. '242 332,182 " data-label="svg" class="linestring vector" fill="none" '
|
||||
. 'stroke="#b02ee0" stroke-width="2" id="svg1234567890"/>',
|
||||
],
|
||||
];
|
||||
|
||||
@ -237,15 +237,15 @@ class GisMultiPointTest extends GisGeomTestCase
|
||||
'svg',
|
||||
[176, 46, 224],
|
||||
new ScaleData(offsetX: 12, offsetY: 69, scale: 2, height: 150),
|
||||
'<circle cx="72" cy="138" r="3" name="svg" class="multipoint '
|
||||
'<circle cx="72" cy="138" r="3" data-label="svg" class="multipoint '
|
||||
. 'vector" fill="white" stroke="#b02ee0" stroke-width="2" id="'
|
||||
. 'svg1234567890"/><circle cx="114" cy="242" r="3" name="svg" class="mult'
|
||||
. 'svg1234567890"/><circle cx="114" cy="242" r="3" data-label="svg" class="mult'
|
||||
. 'ipoint vector" fill="white" stroke="#b02ee0" stroke-width="2" id'
|
||||
. '="svg1234567890"/><circle cx="26" cy="198" r="3" name="svg" class='
|
||||
. '="svg1234567890"/><circle cx="26" cy="198" r="3" data-label="svg" class='
|
||||
. '"multipoint vector" fill="white" stroke="#b02ee0" stroke-width='
|
||||
. '"2" id="svg1234567890"/><circle cx="4" cy="182" r="3" name="svg" '
|
||||
. '"2" id="svg1234567890"/><circle cx="4" cy="182" r="3" data-label="svg" '
|
||||
. 'class="multipoint vector" fill="white" stroke="#b02ee0" stroke-'
|
||||
. 'width="2" id="svg1234567890"/><circle cx="46" cy="132" r="3" name='
|
||||
. 'width="2" id="svg1234567890"/><circle cx="46" cy="132" r="3" data-label='
|
||||
. '"svg" class="multipoint vector" fill="white" stroke="#b02ee0" '
|
||||
. 'stroke-width="2" id="svg1234567890"/>',
|
||||
],
|
||||
|
||||
@ -349,10 +349,12 @@ class GisMultiPolygonTest extends GisGeomTestCase
|
||||
[176, 46, 224],
|
||||
new ScaleData(offsetX: -50, offsetY: -50, scale: 2, height: 400),
|
||||
'<path d=" M 110, 290 L 290, 290 L 290, 110 L 110, 110 Z M 120, 280 L 120, 220 L 180, 220 L 180, 28'
|
||||
. '0 Z M 220, 180 L 280, 180 L 280, 120 L 220, 120 Z " name="svg" class="multipolygon vector" stroke='
|
||||
. '0 Z M 220, 180 L 280, 180 L 280, 120 L 220, 120 Z " data-label="svg" class="multipolygon vector"'
|
||||
. ' stroke='
|
||||
. '"black" stroke-width="0.5" fill="#b02ee0" fill-rule="evenodd" fill-opacity="0.8" id="svg1234567890"'
|
||||
. '/><path d=" M 90, 310 L -90, 310 L -90, 490 L 90, 490 Z M 80, 320 L 80, 380 L 20, 380 L 20, 320 Z '
|
||||
. ' M -20, 420 L -80, 420 L -80, 480 L -20, 480 Z " name="svg" class="multipolygon vector" stroke="bla'
|
||||
. ' M -20, 420 L -80, 420 L -80, 480 L -20, 480 Z " data-label="svg" class="multipolygon vector"'
|
||||
. ' stroke="bla'
|
||||
. 'ck" stroke-width="0.5" fill="#b02ee0" fill-rule="evenodd" fill-opacity="0.8" id="svg1234567890"/>',
|
||||
],
|
||||
];
|
||||
|
||||
@ -254,7 +254,8 @@ class GisPolygonTest extends GisGeomTestCase
|
||||
'svg',
|
||||
[176, 46, 224],
|
||||
new ScaleData(offsetX: 12, offsetY: 69, scale: 2, height: 150),
|
||||
'<path d=" M 222, 288 L 22, 228 L 10, 162 Z M 174, 264 L 36, 218 L 26, 178 Z " name="svg" id="svg12'
|
||||
'<path d=" M 222, 288 L 22, 228 L 10, 162 Z M 174, 264 L 36, 218 L 26, 178 Z " data-label="svg"'
|
||||
. ' id="svg12'
|
||||
. '34567890" class="polygon vector" stroke="black" stroke-width="0.5" fill="#b02ee0" fill-rule="evenod'
|
||||
. 'd" fill-opacity="0.8"/>',
|
||||
],
|
||||
|
||||
@ -611,7 +611,7 @@ class InsertEditTest extends AbstractTestCase
|
||||
$result = $this->parseString($result);
|
||||
|
||||
self::assertStringContainsString(
|
||||
'<textarea name="fieldsb" class="char charField" '
|
||||
'<textarea name="fieldsb" class="charField" '
|
||||
. 'data-maxlength="10" rows="7" cols="1" dir="ltr" '
|
||||
. 'id="field_2_3" tabindex="2" data-type="CHAR">',
|
||||
$result,
|
||||
@ -751,7 +751,7 @@ class InsertEditTest extends AbstractTestCase
|
||||
|
||||
self::assertSame(
|
||||
"a\na\n"
|
||||
. '<textarea name="fieldsb" class="char charField" '
|
||||
. '<textarea name="fieldsb" class="charField" '
|
||||
. 'data-maxlength="25" rows="7" cols="1" dir="ltr" '
|
||||
. 'id="field_22_3" onchange="c" tabindex="22" data-type="CHAR">'
|
||||
. '<</textarea>',
|
||||
|
||||
Loading…
Reference in New Issue
Block a user