Page MenuHomePhabricator

02-T426631-v2.patch

Authored By
Reedy
Jun 2 2026, 1:58 PM
Size
4 KB
Referenced Files
None
Subscribers
None

02-T426631-v2.patch

From 16917439daab97ddb0a58a7b75d17d47c60535fe Mon Sep 17 00:00:00 2001
From: Kosta Harlan <kharlan@wikimedia.org>
Date: Mon, 18 May 2026 20:02:32 +0200
Subject: [PATCH 2/2] SECURITY: EasyTimeline: Strip newlines from BarData and
Scale text
Why:
- Follow-up to T426631. The original strip only covered TextData,
but ParseBarData and ParseScale have the same shape and were
missed: real LFs introduced by ExtractText survive into the
generated ploticus script as column-0 directives. -noshell
blocks the shell-exec sink today, but the directive-injection
primitive is still attacker-controlled
- The TextData strip regex did not cover bare CR or other
vertical whitespace either
What:
- In ParseBarData, strip vertical whitespace and the literal \n
sequence from the Text= attribute, mapping both to '~'. Closes
injection into the 'stubs: text' block written by WritePlotFile
- In ParseScale, do the same on the Text= attribute before the
existing '~ -> \n' transform. Closes injection into the
'stubs: list' arg written by PlotScale
- Widen the existing ParseTextData strip from /(?:\n|\\n)/ to
/(?:\v|\\n)/ so bare CR and other vertical whitespace are
neutralised consistently with the new sites
Assisted-by: Claude Opus 4.7
Bug: T426631
---
scripts/EasyTimeline.pl | 27 +++++++++++++++++++--------
1 file changed, 19 insertions(+), 8 deletions(-)
diff --git a/scripts/EasyTimeline.pl b/scripts/EasyTimeline.pl
index a865620..048da11 100755
--- a/scripts/EasyTimeline.pl
+++ b/scripts/EasyTimeline.pl
@@ -817,7 +817,13 @@ sub ParseBarData {
# }
elsif ($attribute =~ /^Text$/i) {
$text = $attrvalue;
- $text =~ s/\\n/~/gs;
+ # Strip newline-ish content that would otherwise close
+ # out the BarData label and reach the 'stubs: text'
+ # block of the generated ploticus script as a column-0
+ # directive. \v covers LF, CR and other vertical
+ # whitespace; \\n catches the literal two-char form
+ # that ParseText derives from '~'.
+ $text =~ s/(?:\v|\\n)/~/gs;
if ($text =~ /\~/) {
&Warning( "BarData attribute 'text' contains ~ (tilde).\n"
. "Tilde will not be translated into newline character (only in PlotData)"
@@ -2519,6 +2525,10 @@ sub ParseScale {
delete($Attributes{"grid"});
}
elsif ($attribute =~ /Text/i) {
+ # Strip newline-ish content that would otherwise close out
+ # the 'stubs: list' arg in PlotScale and reach the
+ # generated ploticus script as a column-0 directive.
+ $attrvalue =~ s/(?:\v|\\n)/~/gs;
$attrvalue =~ s/\~/\\n/g;
$attrvalue =~ s/^\"//g;
$attrvalue =~ s/\"$//g;
@@ -2727,13 +2737,14 @@ sub ParseTextData {
# Strip newline-ish content that would otherwise
# survive WriteText mode "^" (which splits only on
# caret) and reach the generated ploticus script.
- # Two forms can arrive here: a real newline char,
- # produced by ExtractText from a 'text:"...\n..."'
- # value, and the literal two-char sequence \n that
- # ParseText derives from '~'. Both are mapped to '~'
- # so they cannot close out the ploticus 'text:'
- # attribute and inject column-0 directives.
- $text =~ s/(?:\n|\\n)/~/gs;
+ # Two forms can arrive here: real vertical whitespace
+ # (LF / CR / VT / FF / etc.) produced by ExtractText
+ # from a 'text:"...\n..."' value, and the literal
+ # two-char sequence \n that ParseText derives from
+ # '~'. Both are mapped to '~' so they cannot close out
+ # the ploticus 'text:' attribute and inject column-0
+ # directives.
+ $text =~ s/(?:\v|\\n)/~/gs;
if ($text =~ /\~/) {
&Warning("TextData attribute 'text' contains ~ (tilde).\n"
. "Tilde will not be translated into newline character (only in PlotData)"
--
2.50.1 (Apple Git-155)

File Metadata

Mime Type
text/x-diff
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
26480801
Default Alt Text
02-T426631-v2.patch (4 KB)

Event Timeline

Reedy changed the visibility from "Custom Policy" to "Custom Policy".