More checks against invalid input.

This commit is contained in:
barnold 2022-09-22 16:28:19 +01:00
parent ff61ab78a9
commit 07fdc53c95
4 changed files with 49 additions and 12 deletions

View File

@ -3,6 +3,30 @@ use Mojo::Base 'Mojolicious', -signatures;
# Define home-made helpers.
sub add_my_helpers ($self) {
$self->helper(
# Return either the nonnegative integer that $maybe_nn is or
# resembles, or return undef if it looks bogus. There's surely
# a utility somewhere to do this already but I didn't find it.
accept_nnint => sub ($self, $maybe_nn) {
my $verdict = do {
if ($maybe_nn =~ m/^[[:digit:]]+$/) {
$maybe_nn;
} elsif ((!defined $maybe_nn) || ($maybe_nn eq '')) {
0;
} else {
undef;
}
};
return $verdict;
}
);
$self->helper(
accept_posint => sub ($self, $maybe_nn) {
my $maybe_pos = $self->accept_nnint($maybe_nn);
return ((defined $maybe_pos) && 0 < $maybe_pos)
? $maybe_pos : undef ;
}
);
$self->helper(
commify => sub ($self, $number) {
my $rev = reverse $number;

View File

@ -29,11 +29,12 @@ sub logout ($self) {
}
sub preferences ($self) {
$self->session(
rows_per_page => max(
1, min($self->max_rpp, $self->param('rows_per_page'))
)
);
my $rpp = $self->accept_posint($self->param('rows_per_page'));
if ((!defined $rpp) || $rpp < 1 || $rpp > $self->max_rpp) {
$self->redirect_to('not_found');
return
}
$self->session(rows_per_page => $rpp);
$self->flash(
confirmation => sprintf("Updated rows per page to %s.", $self->rpp)
);

View File

@ -4,8 +4,8 @@ use MyModel::Book;
use MyModel::Author;
sub books ($self) {
my $page_number = $self->param('page_number') // 1;
if ($page_number < 1) {
my $page_number = $self->accept_posint($self->param('page_number'));
if (!defined $page_number) {
$self->redirect_to('not_found');
return;
}
@ -27,8 +27,9 @@ sub books ($self) {
}
sub authors ($self) {
my $page_number = $self->param('page_number') // 1;
if ($page_number < 1) {
my $page_number = $self->accept_posint($self->param('page_number'));
my $mbcount = $self->accept_nnint($self->param('minimum_book_count'));
if ((!defined $page_number) || (!defined $mbcount)) {
$self->redirect_to('not_found');
return;
}
@ -36,7 +37,7 @@ sub authors ($self) {
my $author_page = $author_model->get_page(
$page_number,
$self->param('name_like'),
$self->param('minimum_book_count') + 0, # cast blank to 0
$mbcount,
);
my $pager = $author_page->pager;
if ($page_number > $pager->last_page) {
@ -50,8 +51,10 @@ sub authors ($self) {
}
sub author ($self) {
my ($id, $page_number) = ($self->param('id'), $self->param('page_number'));
if ($page_number < 1) {
my ($id, $page_number) = (
$self->param('id'), $self->accept_posint($self->param('page_number'))
);
if (!defined $page_number) {
$self->redirect_to('not_found');
return;
}

View File

@ -15,7 +15,16 @@ $t->get_ok('/books/0')->status_is(404);
# Likewise for a too-high page number.
$t->get_ok('/books/999?title_like=qxqxqxqx')->status_is(404);
# Likewise for invalid page numbers.
$t->get_ok('/books/x')->status_is(404);
$t->get_ok('/books/1.99')->status_is(404);
$t->get_ok('/books/-42')->status_is(404);
# Or non-existent author.
$t->get_ok('/author/0/1')->status_is(404);
# Invalid number of books for authors.
$t->get_ok('/authors/1?minimum_book_count=banana')->status_is(404);
$t->get_ok('/authors/1?minimum_book_count=-2')->status_is(404);
done_testing();