The string could be static, but it could still contain mal-formated content, so I don't think mixing the two ideas is a good thing to do.
You could easily have:
use constant FOO => ">foo<";
$tx->render(..., {foo => FOO});
It's okay if all variables are perfectly controlled by you and your developers, but you probably have many different inputs, not all of which are html-safe. I'm also willing to bet there's going to be that one person in your team who's going to insert a possible XSS in the future when you're least prepared.
If you're sure your variables are static and html-safe, maybe what you need to do is to mark them raw when you're declaring them, or when you're passing them to Xslate
use Text::Xslate qw(mark_raw);
use constant FOO => mark_raw("foo");
my $tx = ...
$tx->render("template.tx", {
foo => FOO,
bar => mark_raw("bar"),
});
If you were to implement it anyway, I see a big problem in the way to determine if a string is "static string" is in Perl. More precisely, with all the existing workarounds for "constant" strings in Perl how far do we go to detect them?
For example.. "use constant" could be easy. There's that READONLY flag:
$ perl -MDevel::Peek -E 'use constant FOO => "foo"; Dump(FOO)'
SV = PV(0x7ffc73859f40) at 0x7ffc73878630
REFCNT = 2
FLAGS = (PADMY,POK,READONLY,pPOK)
PV = 0x7ffc7341b130 "foo"\0
CUR = 3
LEN = 16
Literal strings passed... hmm, still not bad.
$ perl -MDevel::Peek -E 'Dump("foo")'
SV = PV(0x7ff54205c390) at 0x7ff5420033a8
REFCNT = 1
FLAGS = (POK,READONLY,pPOK)
PV = 0x7ff541c0d660 "foo"\0
CUR = 3
LEN = 16
But the moment you assign that string into a scalar, it's no longer readonly!
$ perl -MDevel::Peek -E 'my $foo = "foo"; Dump($foo)'
SV = PV(0x7fa36a804070) at 0x7fa36a8033a8
REFCNT = 1
FLAGS = (PADMY,POK,pPOK)
PV = 0x7fa36a405980 "foo"\0
CUR = 3
LEN = 16
What if we use other approaches like Readonly.pm ? :
$ perl -MReadonly -MDevel::Peek -E 'Readonly::Scalar my $foo => "foo"; Dump($foo)'
SV = PVMG(0x7ff8b1059200) at 0x7ff8b10033a8
REFCNT = 1
FLAGS = (PADMY,GMG,SMG,RMG)
IV = 0
NV = 0
PV = 0
MAGIC = 0x7ff8b0d05820
MG_VIRTUAL = &PL_vtbl_packelem
MG_TYPE = PERL_MAGIC_tiedscalar(q)
MG_FLAGS = 0x02
REFCOUNTED
MG_OBJ = 0x7ff8b10034c8
SV = IV(0x7ff8b10034b8) at 0x7ff8b10034c8
REFCNT = 1
FLAGS = (ROK)
RV = 0x7ff8b10958a8
SV = PVMG(0x7ff8b10591a0) at 0x7ff8b10958a8
REFCNT = 1
FLAGS = (PADMY,OBJECT,POK,pPOK)
IV = 0
NV = 0
PV = 0x7ff8b0d03ce0 "foo"\0
CUR = 3
LEN = 16
STASH = 0x7ff8b104baf0 "Readonly::Scalar"
Eek.
If you only support "use constant", then the behavior changes for a very particular subset of inputs. the moment you have enough variables, I can see all sorts of havoc breaking loose. And supporting all those different ways to mark a string constant doesn't sound realistic.
Now, taking a step back. If the user is ABSOLUTELY sure that none of the above worst cases are going to happen, then maybe the correct way to handle this is to allow changing the default filtering to an arbitrary Perl subroutine:
my $tx = Text::Xslate->new( default_filter => sub { "unsafe filtering that tries to check for READONLY flags" } );
This to me sounds... okay. Because then you're clearly stating you want to shoot your own foot :)
However, since this operation would be applied to pretty much all variable output, it would certainly slow down Text::Xslate, and again, I'm not sure if it's worth it, which brings back to my earlier proposition to explicitly marking them strings raw before hand
--d