Pg: Be more strict with boolean bind parameters
Reason for this is that, with FU::SQL, it's possible to accidentally introduce a bind parameter when a WHERE clause was intended (i.e. "WHERE $1"). That's pretty bad, but can easily be caught by simply not accepting *every* possible value as boolean.
This commit is contained in:
parent
02b1dcc328
commit
a7868f74bf
3 changed files with 26 additions and 8 deletions
10
FU/Pg.pm
10
FU/Pg.pm
|
|
@ -631,10 +631,12 @@ Some built-in types deserve a few additional notes:
|
|||
|
||||
=item bool
|
||||
|
||||
Boolean values are converted to C<builtin::true> and C<builtin::false>. As bind
|
||||
parameters, Perl's idea of truthiness is used: C<0>, C<false> and C<""> are
|
||||
false, everything else is true. Objects that overload I<bool> are also
|
||||
supported. C<undef> always converts to SQL C<NULL>.
|
||||
Boolean values are converted to C<builtin::true> and C<builtin::false>.
|
||||
|
||||
As bind parameters, values recognized by C<to_bool()> in L<FU::Util> are
|
||||
accepted, in addition to C<0>, C<"f"> and C<""> for false and C<1>, and C<"t">
|
||||
for true. C<undef> always converts to SQL C<NULL>. Everything else throws an
|
||||
error.
|
||||
|
||||
=item bytea
|
||||
|
||||
|
|
|
|||
11
c/pgtypes.c
11
c/pgtypes.c
|
|
@ -82,8 +82,15 @@ RECVFN(bool) {
|
|||
}
|
||||
|
||||
SENDFN(bool) {
|
||||
int r = fu_2bool(aTHX_ val); /* So that we also recognize \0 and \1 */
|
||||
fustr_write_ch(out, r < 0 ? SvTRUE(val) : r);
|
||||
int r = fu_2bool(aTHX_ val);
|
||||
if (r < 0) {
|
||||
STRLEN l;
|
||||
const char *x = SvPV(val, l);
|
||||
if (l == 0 || (l == 1 && (*x == '0' || *x == 'f'))) r = 0;
|
||||
else if (l == 1 && (*x == '1' || *x == 't')) r = 1;
|
||||
else SERR("invalid boolean value: %s", x);
|
||||
}
|
||||
fustr_write_ch(out, r);
|
||||
}
|
||||
|
||||
RECVFN(void) {
|
||||
|
|
|
|||
13
t/pgtypes.t
13
t/pgtypes.t
|
|
@ -61,8 +61,17 @@ sub f($type, $p_in) {
|
|||
$array->[0] = 0;
|
||||
}
|
||||
|
||||
v bool => true, undef, 1, 't';
|
||||
v bool => false, undef, 0, 'f';
|
||||
v bool => true, true, 1, 't';
|
||||
v bool => \1, true, 1, 't';
|
||||
v bool => 1, true, 1, 't';
|
||||
v bool => 't', true, 1, 't';
|
||||
v bool => false, false, 0, 'f';
|
||||
v bool => \0, false, 0, 'f';
|
||||
v bool => 0, false, 0, 'f';
|
||||
v bool => '', false, 0, 'f';
|
||||
v bool => 'f', false, 0, 'f';
|
||||
f bool => 2;
|
||||
f bool => [];
|
||||
|
||||
v int2 => $_ for (1, -1, -32768, 32767, '12345', -12345, 123.0);
|
||||
f int2 => $_ for (-32769, 32768, [], '', 'a', 1.5);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue