PerlDancer / PerlDancer/Dancer2
params('body') dies with 'Not a HASH reference' on a JSON array body
Nobody has claimed this yet.
- Dominant language
- Perl
- Stars
- 604
- Forks
- 288
- Avg merge
- 1d 5h
- Merged PRs (30d)
- 5
Description
Status: confirmed against main @ 21bc21d9
lib/Dancer2/Core/Request.pm:351:
return %{ $self->_body_params || {} } if wantarray;
The || {} guards undef but not a non-hash reference. deserialize (line 238) assigns whatever the serializer returned straight into _body_params, and a JSON array or bare scalar body is perfectly legal JSON.
Reproduction
perl -Ilib -e 'use Dancer2::Serializer::JSON; use Dancer2::Core::Request;
open my $fh, "<", \q{[1,2,3]};
my $r = Dancer2::Core::Request->new(serializer=>Dancer2::Serializer::JSON->new,
env=>{REQUEST_METHOD=>"POST",PATH_INFO=>"/",QUERY_STRING=>"",CONTENT_TYPE=>"application/json",
CONTENT_LENGTH=>7,"psgi.input"=>$fh,"psgi.url_scheme"=>"http",SERVER_NAME=>"l",SERVER_PORT=>80});
my @p = eval { $r->params("body") }; print $@ ? "DIED: $@" : "ok\n"'
DIED: Not a HASH reference at lib/Dancer2/Core/Request.pm line 351.
Impact
Any application calling params('body') in list context can be 500'd by an unauthenticated request with a JSON array body.
Suggested fix
elsif ( $source eq 'body' ) {
my $p = $self->_body_params;
return ( is_hashref($p) ? %{$p} : () ) if wantarray;
return $p;
}
is_hashref is already imported at line 14. Apply the same guard to the query branch for symmetry.
Worth deciding explicitly: whether returning the raw non-hash value in scalar context is the right contract, or whether it should be undef. body_data (line 690) has its own opinion about this, and the two should agree.
Suggested test
A JSON body of [1,2,3] does not 500 via params('body') in list context.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in lib/Dancer2/Core/Request.pm at params around line 351 and deserialize around line 238, then compare body_data around line 690. Reproduce with the provided JSON array request and add a regression test showing params('body') in list context does not die. Done when the non-hash body behavior is consistent with the chosen scalar-context contract and the regression passes.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- perl
- Domain
- api, backend
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 78/100