From d5e6d99aa238054b426aa2b714c532e8ed8b13c1 Mon Sep 17 00:00:00 2001 From: David Precious Date: Thu, 7 Dec 2023 11:24:32 +0000 Subject: [PATCH] Handle multi-line sub attributes For use with Catalyst::Plugin::CheckFileUploadTypes, I needed to provide a fairly long list of acceptable MIME types. This means that my handler code would be e.g.: ```perl sub index_POST: ExpectUploads(image/png image/jpeg application/pdf) { ... } ``` ... which is fine, but the list of types to support grew longer and longer, not helped by some very long MIME types such as `application/vnd.openxmlformats-officedocument.wordprocessingml.document` So, I wanted to make it much more readable, for e.g.: ```perl sub index_POST: ExpectUploads( image/jpeg image/png image/bmp application/pdf application/vnd.openxmlformats-officedocument.wordprocessingml.document application/vnd.openxmlformats-officedocument.spreadsheetml.sheet ) { ... } ``` That looks like it should be fine, but failed, because the code in `Catalyst::Controller::_parse_attrs()` which parse subroutine attributes expected it to be all on line line. This change makes it work correctly for me, both for single-line attributes with and without a value and for multi-lined ones as per the example above too - and makes the parsing code a little more readable too, I think. --- lib/Catalyst/Controller.pm | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/lib/Catalyst/Controller.pm b/lib/Catalyst/Controller.pm index 34ad3505f..661fa5495 100644 --- a/lib/Catalyst/Controller.pm +++ b/lib/Catalyst/Controller.pm @@ -400,14 +400,22 @@ sub _parse_attrs { my %raw_attributes; foreach my $attr (@attrs) { - # Parse out :Foo(bar) into Foo => bar etc (and arrayify) - - if ( my ( $key, $value ) = ( $attr =~ /^(.*?)(?:\(\s*(.+?)?\s*\))?$/ ) ) + if ( my ( $key, $value ) = $attr =~ m{ + \A + (\S*?) # match the key e.g. Foo in example + (?: + \( \s* + (.+?)? # match attr content e.g. "bar" in example + \s* \) + )? + \z + }xms ) { if ( defined $value ) { - ( $value =~ s/^'(.*)'$/$1/ ) || ( $value =~ s/^"(.*)"/$1/ ); + # Unquote single/double quoted attr values e.g. Foo("bar") + ( $value =~ s/^'(.*)'$/$1/s ) || ( $value =~ s/^"(.*)"/$1/s ); } push( @{ $raw_attributes{$key} }, $value ); }