summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/VNDB/DB/Staff.pm11
-rw-r--r--lib/VNDB/Func.pm30
-rw-r--r--lib/VNDB/Handler/Staff.pm28
3 files changed, 44 insertions, 25 deletions
diff --git a/lib/VNDB/DB/Staff.pm b/lib/VNDB/DB/Staff.pm
index 1b9a10da..4dfe0756 100644
--- a/lib/VNDB/DB/Staff.pm
+++ b/lib/VNDB/DB/Staff.pm
@@ -126,7 +126,7 @@ sub dbStaffRevisionInsert {
my($self, $o) = @_;
$self->dbExec('DELETE FROM edit_staff_aliases');
- if ($o->{aid}) {
+ if($o->{aid}) {
$self->dbExec(q|
INSERT INTO edit_staff_aliases (id, name, original) VALUES (?, ?, ?)|,
$o->{aid}, $o->{name}, $o->{original});
@@ -139,12 +139,11 @@ sub dbStaffRevisionInsert {
my %staff = map exists($o->{$_}) ? (qq|"$_" = ?|, $o->{$_}) : (),
qw|aid gender lang desc l_wp l_site l_twitter l_anidb|;
$self->dbExec('UPDATE edit_staff !H', \%staff) if %staff;
- for my $alias (@{$o->{aliases}}) {
- if ($alias->[0]) {
- $self->dbExec('INSERT INTO edit_staff_aliases (id, name, original) VALUES (!l)', $alias);
+ for my $a (@{$o->{aliases}}) {
+ if($a->{aid}) {
+ $self->dbExec('INSERT INTO edit_staff_aliases (id, name, original) VALUES (!l)', [ @{$a}{qw|aid name orig|} ]);
} else {
- $self->dbExec('INSERT INTO edit_staff_aliases (name, original) VALUES (?, ?)',
- $alias->[1], $alias->[2]);
+ $self->dbExec('INSERT INTO edit_staff_aliases (name, original) VALUES (?, ?)', $a->{name}, $a->{orig});
}
}
}
diff --git a/lib/VNDB/Func.pm b/lib/VNDB/Func.pm
index ac9fdd58..dd3f292e 100644
--- a/lib/VNDB/Func.pm
+++ b/lib/VNDB/Func.pm
@@ -3,7 +3,7 @@ package VNDB::Func;
use strict;
use warnings;
-use TUWF ':html';
+use TUWF ':html', 'kv_validate';
use Exporter 'import';
use POSIX 'strftime', 'ceil', 'floor';
use JSON::XS;
@@ -11,7 +11,7 @@ use VNDBUtil;
our @EXPORT = (@VNDBUtil::EXPORT, qw|
clearfloat cssicon tagscore mt minage fil_parse fil_serialize parenttags
childtags charspoil imgpath imgurl fmtvote
- jsonEncode jsonDecode script_json
+ jsonEncode jsonDecode script_json json_validate
mtvoiced mtani mtvnlen mtrlstat mtvnlstat mtbloodt
|);
@@ -228,6 +228,32 @@ sub script_json {
}
+# Special validation function for simple JSON structures as form fields. It can
+# only validate arrays of key-value objects. The key-value objects are then
+# validated using kv_validate.
+# Returns the parsed json object on success, undef on error and sets $frm->{_err}.
+# Doesn't provide a user-friendly error message if validation fails. It's the
+# responsibility of the JS code to handle the interface with the user.
+sub json_validate {
+ my($frm, $name, @fields) = @_;
+ my $data = eval { jsonDecode $frm->{$name} };
+ goto error if $@ || ref $data ne 'ARRAY';
+ my %known_fields = map +($_->{field},1), @fields;
+ for my $i (0..$#$data) {
+ goto error if ref $data->[$i] ne 'HASH';
+ # Require that all keys are known and have a scalar value.
+ goto error if grep !$known_fields{$_} || ref($data->[$i]{$_}), keys %{$data->[$i]};
+ $data->[$i] = kv_validate({ field => sub { $data->[$i]{shift()} } }, $TUWF::OBJ->{_TUWF}{validate_templates}, \@fields);
+ goto error if $data->[$i]{_err};
+ }
+
+ return $data;
+error:
+ push @{$frm->{_err}}, [ 'aliases', 'template', 'json' ] ;
+ return undef;
+}
+
+
# mt() wrappers for data-dependent translation strings that have a special
# value for 'unknown'.
sub mtvoiced { !$_[0] ? mt '_unknown' : mt '_voiced_'.$_[0]; }
diff --git a/lib/VNDB/Handler/Staff.pm b/lib/VNDB/Handler/Staff.pm
index 3c8fd7af..2840442b 100644
--- a/lib/VNDB/Handler/Staff.pm
+++ b/lib/VNDB/Handler/Staff.pm
@@ -215,29 +215,23 @@ sub edit {
{ post => 'ilock', required => 0 },
);
push @{$frm->{_err}}, 'badeditsum' if !$frm->{editsum} || lc($frm->{editsum}) eq lc($frm->{desc});
+ my $aliases = json_validate($frm, 'aliases',
+ { field => 'name', required => 1, maxlength => 200 },
+ { field => 'orig', required => 0, maxlength => 200, default => '' },
+ { field => 'aid', required => 0, template => 'int', default => 0 },
+ );
- my @aliases;
- my $raw_a = eval { jsonDecode $frm->{aliases} };
- push @{$frm->{_err}}, [ 'aliases', 'template', 'json' ] if $@ || ref $raw_a ne 'ARRAY';
if(!$frm->{_err}) {
+ $aliases = [ sort { $a->{name} cmp $b->{name} } @$aliases ];
my %old_aliases = $sid ? ( map +($_->{id} => 1), @{$self->dbStaffAliasIds($sid)} ) : ();
$frm->{primary} = 0 unless exists $old_aliases{$frm->{primary}};
- for my $a (sort { $a->{name} cmp $b->{name} } @$raw_a) {
- # check for empty aliases
- if($a->{name} =~ /^\s*$/) {
- push @{$frm->{_err}}, ['alias_name', 'required'];
- last;
- }
- s/^\s+|\s+$//g for ($a->{name}, $a->{orig});
- # normalize alias id to a number so that the comparison works
- # or reset it to zero for newly added aliases.
- $a->{aid} *= $old_aliases{$a->{aid}} ? 1 : 0;
- push @aliases, $a;
- }
+ # normalize alias id to a number so that the comparison works
+ # or reset it to zero for newly added aliases.
+ $_->{aid} *= $old_aliases{$_->{aid}} ? 1 : 0 for (sort { $a->{name} cmp $b->{name} } @$aliases);
}
if(!$frm->{_err}) {
- $frm->{aliases} = jsonEncode \@aliases;
+ $frm->{aliases} = jsonEncode $aliases;
$frm->{ihid} = $frm->{ihid} ?1:0;
$frm->{ilock} = $frm->{ilock}?1:0;
$frm->{aid} = $frm->{primary} if $sid;
@@ -246,7 +240,7 @@ sub edit {
return $self->resRedirect("/s$sid", 'post')
if $sid && !first { ($frm->{$_}//'') ne ($b4{$_}//'') } keys %b4;
- $frm->{aliases} = [ map [ @{$_}{qw|aid name orig|} ], @aliases ];
+ $frm->{aliases} = $aliases;
my $nrev = $self->dbItemEdit ('s' => $sid ? $s->{cid} : undef, %$frm);
return $self->resRedirect("/s$nrev->{iid}.$nrev->{rev}", 'post');
}