]> git.ipfire.org Git - thirdparty/bugzilla.git/commitdiff
Bug 1851421: Use /a with \d to ensure ASCII digit matches (#225)
authorDave Miller <justdave@bugzilla.org>
Sat, 11 Jul 2026 08:34:32 +0000 (04:34 -0400)
committerGitHub <noreply@github.com>
Sat, 11 Jul 2026 08:34:32 +0000 (04:34 -0400)
r=mrenvoize

72 files changed:
Bugzilla/Attachment.pm
Bugzilla/Bug.pm
Bugzilla/BugUrl/Debian.pm
Bugzilla/BugUrl/GitHub.pm
Bugzilla/BugUrl/Google.pm
Bugzilla/BugUrl/JIRA.pm
Bugzilla/BugUrl/Launchpad.pm
Bugzilla/BugUrl/MantisBT.pm
Bugzilla/BugUrl/Trac.pm
Bugzilla/CGI.pm
Bugzilla/Chart.pm
Bugzilla/Comment.pm
Bugzilla/Config/Common.pm
Bugzilla/DB/Oracle.pm
Bugzilla/DB/Pg.pm
Bugzilla/Extension.pm
Bugzilla/Flag.pm
Bugzilla/Install/DB.pm
Bugzilla/Install/Filesystem.pm
Bugzilla/Install/Requirements.pm
Bugzilla/Install/Util.pm
Bugzilla/Mailer.pm
Bugzilla/Migrate/Gnats.pm
Bugzilla/Object.pm
Bugzilla/RNG.pm
Bugzilla/Search.pm
Bugzilla/Search/Quicksearch.pm
Bugzilla/Search/Saved.pm
Bugzilla/Template.pm
Bugzilla/Update.pm
Bugzilla/User.pm
Bugzilla/Util.pm
Bugzilla/Version.pm
Bugzilla/WebService/Bug.pm
Bugzilla/WebService/Server/REST.pm
Bugzilla/WebService/Server/REST/Resources/Bug.pm
Bugzilla/WebService/Server/REST/Resources/BugUserLastVisit.pm
Bugzilla/WebService/Server/REST/Resources/Classification.pm
Bugzilla/WebService/Server/REST/Resources/FlagType.pm
Bugzilla/WebService/Server/REST/Resources/Group.pm
Bugzilla/WebService/Server/REST/Resources/Product.pm
Bugzilla/WebService/Server/REST/Resources/User.pm
buglist.cgi
chart.cgi
contrib/bzdbcopy.pl
contrib/console.pl
contrib/merge-users.pl
contrib/sendbugmail.pl
editproducts.cgi
email_in.pl
extensions/Example/Extension.pm
extensions/MoreBugUrl/lib/BitBucket.pm
extensions/MoreBugUrl/lib/PHP.pm
extensions/MoreBugUrl/lib/RT.pm
extensions/MoreBugUrl/lib/Redmine.pm
extensions/MoreBugUrl/lib/ReviewBoard.pm
extensions/MoreBugUrl/lib/Rietveld.pm
extensions/MoreBugUrl/lib/Savane.pm
extensions/MoreBugUrl/lib/WineHQForums.pm
extensions/Voting/Extension.pm
importxml.pl
process_bug.cgi
query.cgi
report.cgi
reports.cgi
show_bug.cgi
showdependencygraph.cgi
showdependencytree.cgi
testserver.pl
userprefs.cgi
whine.pl
xt/lib/Bugzilla/Test/Search/FieldTest.pm

index 4e81e31669fa0d96736f72fa16645e72897d3e2a..1ec554bb993567c211756f46d05919936b287300 100644 (file)
@@ -385,7 +385,7 @@ sub datasize {
 sub _get_local_filename {
   my $self = shift;
   my $hash = ($self->id % 100) + 100;
-  $hash =~ s/.*(\d\d)$/group.$1/;
+  $hash =~ s/.*(\d\d)$/group.$1/a;
   return bz_locations()->{'attachdir'} . "/$hash/attachment." . $self->id;
 }
 
@@ -844,7 +844,7 @@ sub create {
   if ($size > Bugzilla->params->{'maxattachmentsize'} * 1024) {
     my $attachdir = bz_locations()->{'attachdir'};
     my $hash      = ($attachid % 100) + 100;
-    $hash =~ s/.*(\d\d)$/group.$1/;
+    $hash =~ s/.*(\d\d)$/group.$1/a;
     mkdir "$attachdir/$hash", 0770;
     chmod 0770, "$attachdir/$hash";
     if (ref $data) {
index d34a5cc13c957b60596184bc37a8af5a64756de7..4af294071847c1dabd7b60e4af7b8fbe3fed0e7e 100644 (file)
@@ -1417,7 +1417,7 @@ sub _check_alias {
     }
 
     # Make sure the alias isn't just a number.
-    if ($alias =~ /^\d+$/) {
+    if ($alias =~ /^\d+$/a) {
       ThrowUserError("alias_is_numeric", {alias => $alias});
     }
 
@@ -1758,7 +1758,7 @@ sub _check_dependencies {
 
     # Replace all aliases by their corresponding bug ID.
     @bug_ids
-      = map { $_ =~ /^(\d+)$/ ? $1 : $invocant->check($_, $type)->id } @bug_ids;
+      = map { $_ =~ /^(\d+)$/a ? $1 : $invocant->check($_, $type)->id } @bug_ids;
     $deps_in{$type} = \@bug_ids;
   }
 
index d1b2633174f0c8fe46c3511e6bf9a58130e51cc7..b42cec2d0c0ebd7c862d8dd14bd6ea872ffa4343 100644 (file)
@@ -26,8 +26,8 @@ sub should_handle {
   return (
     lc($uri->authority) eq 'bugs.debian.org'
       and
-      (($uri->path =~ /bugreport\.cgi$/ and $uri->query_param('bug') =~ m|^\d+$|)
-      or $uri->path =~ m|^/\d+$|)
+      (($uri->path =~ /bugreport\.cgi$/ and $uri->query_param('bug') =~ m|^\d+$|a)
+      or $uri->path =~ m|^/\d+$|a)
   ) ? 1 : 0;
 }
 
@@ -38,7 +38,7 @@ sub _check_value {
 
   # This is the shortest standard URL form for Debian BTS URLs,
   # and so we reduce all URLs to this.
-  $uri->path =~ m|^/(\d+)$| || $uri->query_param('bug') =~ m|^(\d+)$|;
+  $uri->path =~ m|^/(\d+)$|a || $uri->query_param('bug') =~ m|^(\d+)$|a;
   $uri = new URI("http://bugs.debian.org/$1");
 
   return $uri;
index 795a8e317f2bf318c8cc2156ce955624d9ab56e9..884fbe07b8057af5a8808c94ccef186bed5cc384 100644 (file)
@@ -25,7 +25,7 @@ sub should_handle {
 # GitHub pull request URLs have only one form:
 #  https://github.com/USER_OR_TEAM_OR_ORGANIZATION_NAME/REPOSITORY_NAME/pull/111
   return (lc($uri->authority) eq 'github.com'
-      and $uri->path =~ m!^/[^/]+/[^/]+/(?:issues|pull)/\d+$!) ? 1 : 0;
+      and $uri->path =~ m!^/[^/]+/[^/]+/(?:issues|pull)/\d+$!a) ? 1 : 0;
 }
 
 sub _check_value {
index e59655d68c7b341773d41a9a1254000c560691a3..31a7b3c72914f8c7c0cfb59edb461947af9062d7 100644 (file)
@@ -24,7 +24,7 @@ sub should_handle {
   #   http(s)://code.google.com/p/PROJECT_NAME/issues/detail?id=1234
   return (lc($uri->authority) eq 'code.google.com'
       and $uri->path =~ m|^/p/[^/]+/issues/detail$|
-      and $uri->query_param('id') =~ /^\d+$/) ? 1 : 0;
+      and $uri->query_param('id') =~ /^\d+$/a) ? 1 : 0;
 }
 
 sub _check_value {
index 251f054279024826802b91ecd78ccaf94a933aa7..219f7978a0561bf3550684a5f5d97f40de864e5c 100644 (file)
@@ -23,7 +23,7 @@ sub should_handle {
   # JIRA URLs have only one basic form (but the jira is optional):
   #   https://issues.apache.org/jira/browse/KEY-1234
   #   http://issues.example.com/browse/KEY-1234
-  return ($uri->path =~ m|/browse/[A-Z][A-Z]+-\d+$|) ? 1 : 0;
+  return ($uri->path =~ m|/browse/[A-Z][A-Z]+-\d+$|a) ? 1 : 0;
 }
 
 sub _check_value {
index e277957735658f26fe3fc9cc425023c2ee447623..820102d8a8b1296d0d1685c4f3890e84fbbfb225 100644 (file)
@@ -24,7 +24,7 @@ sub should_handle {
   #   https://bugs.launchpad.net/ubuntu/+bug/1234
   #   https://launchpad.net/bugs/1234
   # All variations end with either "/bugs/1234" or "/+bug/1234"
-  return ($uri->authority =~ /launchpad\.net$/ and $uri->path =~ m|bugs?/\d+$|)
+  return ($uri->authority =~ /launchpad\.net$/ and $uri->path =~ m|bugs?/\d+$|a)
     ? 1
     : 0;
 }
@@ -36,7 +36,7 @@ sub _check_value {
 
   # This is the shortest standard URL form for Launchpad bugs,
   # and so we reduce all URLs to this.
-  $uri->path =~ m|bugs?/(\d+)$|;
+  $uri->path =~ m|bugs?/(\d+)$|a;
   $uri = new URI("https://launchpad.net/bugs/$1");
 
   return $uri;
index 8b7e66669b940c68581c6af0449efd68bde2de09..3b147cbc44f0f333d41ffa782ac28e539b63b957 100644 (file)
@@ -22,7 +22,7 @@ sub should_handle {
 
   # MantisBT URLs look like the following ('bugs' directory is optional):
   #   http://www.mantisbt.org/bugs/view.php?id=1234
-  return ($uri->path_query =~ m|view\.php\?id=\d+$|) ? 1 : 0;
+  return ($uri->path_query =~ m|view\.php\?id=\d+$|a) ? 1 : 0;
 }
 
 sub _check_value {
index 51dd414ff9f9be235ecf78ac5106cbd1ca7dc200..38470f06b1493a31b9d8c5d517606c1c72be79e2 100644 (file)
@@ -23,7 +23,7 @@ sub should_handle {
   # Trac URLs can look like various things:
   #   http://dev.mutt.org/trac/ticket/1234
   #   http://trac.roundcube.net/ticket/1484130
-  return ($uri->path =~ m|/ticket/\d+$|) ? 1 : 0;
+  return ($uri->path =~ m|/ticket/\d+$|a) ? 1 : 0;
 }
 
 sub _check_value {
index 3057f0f8adb8ba482b3f6b6840cef2c8638b729a..3a578d7932937932f3be240cbc780478ff27d3b6 100644 (file)
@@ -124,7 +124,7 @@ sub canonicalise_query {
 
     # Remove the Boolean Charts for standard query.cgi fields
     # They are listed in the query URL already
-    next if $key =~ /^(field|type|value)(-\d+){3}$/;
+    next if $key =~ /^(field|type|value)(-\d+){3}$/a;
 
     my $esc_key = url_quote($key);
 
@@ -156,7 +156,7 @@ sub clean_search_url {
 
     # Custom Search stuff is empty if it's "noop". We also keep around
     # the old Boolean Chart syntax for backwards-compatibility.
-    if ( ($param =~ /\d-\d-\d/ || $param =~ /^[[:alpha:]]\d+$/)
+    if ( ($param =~ /\d-\d-\d/a || $param =~ /^[[:alpha:]]\d+$/a)
       && defined $self->param($param)
       && $self->param($param) eq 'noop')
     {
@@ -165,7 +165,7 @@ sub clean_search_url {
 
     # Any "join" for custom search that's an AND can be removed, because
     # that's the default.
-    if (($param =~ /^j\d+$/ || $param eq 'j_top') && $self->param($param) eq 'AND')
+    if (($param =~ /^j\d+$/a || $param eq 'j_top') && $self->param($param) eq 'AND')
     {
       $self->delete($param);
     }
@@ -629,7 +629,7 @@ sub url_is_attachment_base {
     # In this circumstance we run quotemeta first because we need to
     # insert an active regex meta-character afterward.
     $regex = quotemeta($attach_base);
-    $regex =~ s/\\\%bugid\\\%/\\d+/;
+    $regex =~ s/\\\%bugid\\\%/(?a:\\d+)/;
   }
   $regex = "^$regex";
   return ($self->url =~ $regex) ? 1 : 0;
index 551f93c7e4ce2b1f5206decb6f6ca8750890010f..54d67b20b7354d8d313e51ab369100a8c5953ba9 100644 (file)
@@ -61,7 +61,7 @@ sub init {
   foreach my $param ($cgi->param()) {
 
     # Store all the lines
-    if ($param =~ /^line(\d+)$/) {
+    if ($param =~ /^line(\d+)$/a) {
       foreach my $series_id ($cgi->param($param)) {
         detaint_natural($series_id) || ThrowCodeError("invalid_series_id");
         my $series = new Bugzilla::Series($series_id);
@@ -70,7 +70,7 @@ sub init {
     }
 
     # Store all the labels
-    if ($param =~ /^label(\d+)$/) {
+    if ($param =~ /^label(\d+)$/a) {
       $self->{'labels'}[$1] = $cgi->param($param);
     }
   }
index ac5341b1e2c4c3d5abf70d19ba6eddebcde440f7..99b2295d3f71c776ade5b870c759a7823636065d 100644 (file)
@@ -458,7 +458,7 @@ sub _check_tag {
     and ThrowUserError('comment_tag_too_short', {tag => $tag});
   length($tag) > MAX_COMMENT_TAG_LENGTH
     and ThrowUserError('comment_tag_too_long', {tag => $tag});
-  $tag =~ /^[\w\d\._-]+$/ or ThrowUserError('comment_tag_invalid', {tag => $tag});
+  $tag =~ /^[\w\._-]+$/ or ThrowUserError('comment_tag_invalid', {tag => $tag});
   return $tag;
 }
 
index f44dd25f0a974a559538e056f1edd468503889d7..1f9c958b519313f3f6e2d4dff946037925154352 100644 (file)
@@ -97,7 +97,7 @@ sub check_sslbase {
 
     # Fall back to port 443 if for some reason getservbyname() fails.
     my $port = getservbyname('https', 'tcp') || 443;
-    if ($host =~ /^(.+):(\d+)$/) {
+    if ($host =~ /^(.+):(\d+)$/a) {
       $host = $1;
       $port = $2;
     }
@@ -353,7 +353,7 @@ sub check_maxattachmentsize {
 sub check_notification {
   my $option = shift;
   my @current_version
-    = (BUGZILLA_VERSION =~ m/^(\d+)\.(\d+)(?:(rc|\.)(\d+))?\+?$/);
+    = (BUGZILLA_VERSION =~ m/^(\d+)\.(\d+)(?:(rc|\.)(\d+))?\+?$/a);
   if ($current_version[1] % 2 && $option eq 'stable_branch_release') {
     return
         "You are currently running a development snapshot, and so your "
index ac2f14a63aee9b1296dcafe852b546d7c99b0a17..30015a0d7a5a523a039774d1dbd6009e072ae278 100644 (file)
@@ -319,7 +319,7 @@ sub adjust_statement {
 
   # Oracle doesn't have LIMIT, so if we find the LIMIT comment, wrap the
   # query with "SELECT * FROM (...) WHERE rownum < $limit"
-  my ($limit, $offset) = ($part =~ m{/\* LIMIT (\d*) (\d*) \*/}o);
+  my ($limit, $offset) = ($part =~ m{/\* LIMIT (\d*) (\d*) \*/}ao);
 
   push @result, $part;
   while (@parts) {
@@ -349,7 +349,7 @@ sub adjust_statement {
     $nonstring =~ s/\bAS\b//ig;
 
     # Look for a LIMIT clause
-    ($limit) = ($nonstring =~ m(/\* LIMIT (\d*) \*/)o);
+    ($limit) = ($nonstring =~ m(/\* LIMIT (\d*) \*/)ao);
 
     if (!length($string)) {
       push @result, EMPTY_STRING;
index 319b7b6c4e09d23b680990fc543be23442e3e342..946945301323c575983be9a5bd783ae0f11eaef5 100644 (file)
@@ -250,7 +250,7 @@ sub bz_check_server_version {
   my $self           = shift;
   my ($db)           = @_;
   my $server_version = $self->SUPER::bz_check_server_version(@_);
-  my ($major_version, $minor_version) = $server_version =~ /^0*(\d+)\.0*(\d+)/;
+  my ($major_version, $minor_version) = $server_version =~ /^0*(\d+)\.0*(\d+)/a;
 
   # Pg 9.0 requires DBD::Pg 2.17.2 in order to properly read bytea values.
   # Pg 9.2 requires DBD::Pg 2.19.3 as spclocation no longer exists.
index b955fa6381a1f69b1b94150707306444f5177b8a..11c5eb27480e8f378c5be36126d4d7eea132dc07 100644 (file)
@@ -52,7 +52,7 @@ sub load {
     }
     else {
       my $name = require $config_file;
-      if ($name =~ /^\d+$/) {
+      if ($name =~ /^\d+$/a) {
         ThrowCodeError('extension_must_return_name',
           {extension => $config_file, returned => $name});
       }
@@ -68,7 +68,7 @@ sub load {
   }
   else {
     my $name = require $extension_file;
-    if ($name =~ /^\d+$/) {
+    if ($name =~ /^\d+$/a) {
       ThrowCodeError('extension_must_return_name',
         {extension => $extension_file, returned => $name});
     }
index 8bbc477477975186178108c586abc0b136ec612b..ccc162aa7446f94d195a6071b11c65c56e0deb4a 100644 (file)
@@ -847,7 +847,7 @@ sub extract_flags_from_cgi {
 
   my $match_status
     = Bugzilla::User::match_field(
-    {'^requestee(_type)?-(\d+)$' => {'type' => 'multi'},},
+    {'(?a:^requestee(_type)?-(\d+)$)' => {'type' => 'multi'},},
     undef, $skip);
 
   $vars->{'match_field'} = 'requestee';
@@ -859,11 +859,11 @@ sub extract_flags_from_cgi {
   }
 
   # Extract a list of flag type IDs from field names.
-  my @flagtype_ids = map(/^flag_type-(\d+)$/ ? $1 : (), $cgi->param());
+  my @flagtype_ids = map(/^flag_type-(\d+)$/a ? $1 : (), $cgi->param());
   @flagtype_ids = grep($cgi->param("flag_type-$_") ne 'X', @flagtype_ids);
 
   # Extract a list of existing flag IDs.
-  my @flag_ids = map(/^flag-(\d+)$/ ? $1 : (), $cgi->param());
+  my @flag_ids = map(/^flag-(\d+)$/a ? $1 : (), $cgi->param());
 
   return ([], []) unless (scalar(@flagtype_ids) || scalar(@flag_ids));
 
@@ -1004,7 +1004,7 @@ sub multi_extract_flags_from_cgi {
 
   my $match_status
     = Bugzilla::User::match_field(
-    {'^requestee(_type)?-(\d+)$' => {'type' => 'multi'},},
+    {'(?a:^requestee(_type)?-(\d+)$)' => {'type' => 'multi'},},
     undef, $skip);
 
   $vars->{'match_field'} = 'requestee';
@@ -1016,7 +1016,7 @@ sub multi_extract_flags_from_cgi {
   }
 
   # Extract a list of flag type IDs from field names.
-  my @flagtype_ids = map(/^flag_type-(\d+)$/ ? $1 : (), $cgi->param());
+  my @flagtype_ids = map(/^flag_type-(\d+)$/a ? $1 : (), $cgi->param());
 
   my (@new_flags, @flags);
 
index 1570a1b4da78af7a85f8e78456760503f2030863..d6f1ba654c45490031b577ea77308283c447c4cb 100644 (file)
@@ -893,7 +893,7 @@ sub _populate_longdescs {
       my $buffer = "";
       foreach my $line (split(/\n/, $desc)) {
         $line =~ s/\s+$//g;    # Trim trailing whitespace.
-        if ($line =~ /^------- Additional Comments From ([^\s]+)\s+(\d.+\d)\s+-------$/)
+        if ($line =~ /^------- Additional Comments From ([^\s]+)\s+((?a:\d.+\d))\s+-------$/)
         {
           my $name = $1;
           my $date = str2time($2);
@@ -1146,7 +1146,7 @@ sub _populate_milestones_table {
 
       # check if the value already exists
       my $sortkey = substr($value, 1);
-      if ($sortkey !~ /^\d+$/) {
+      if ($sortkey !~ /^\d+$/a) {
         $sortkey = 0;
       }
       else {
@@ -1247,7 +1247,7 @@ sub _populate_duplicates_table {
 
     foreach $key (keys(%dupes)) {
       $dupes{$key}
-        =~ /^.*\*\*\* This bug has been marked as a duplicate of (\d+) \*\*\*$/ms;
+        =~ /^.*\*\*\* This bug has been marked as a duplicate of (\d+) \*\*\*$/ams;
       $dupes{$key} = $1;
       $dbh->do("INSERT INTO duplicates VALUES(?, ?)", undef, $dupes{$key}, $key);
 
@@ -2300,7 +2300,7 @@ sub _copy_old_charts_into_database {
 
       my @lines = <$in>;
       while (my $line = shift @lines) {
-        if ($line =~ /^(\d+\|.*)/) {
+        if ($line =~ /^(\d+\|.*)/a) {
           my @numbers = split(/\||\r/, $1);
 
           # Only take the first line for each date; it was possible to
@@ -3580,7 +3580,7 @@ sub _fix_illegal_flag_modification_dates {
 
   # If no rows are affected, $dbh->do returns 0E0 instead of 0.
   print "$rows flags had an illegal modification date. Fixed!\n"
-    if ($rows =~ /^\d+$/);
+    if ($rows =~ /^\d+$/a);
 }
 
 sub _add_visiblity_value_to_value_tables {
@@ -3679,7 +3679,7 @@ sub _set_attachment_comment_type {
   foreach my $id (@comment_ids) {
     $count++;
     my $text = $comments{$id};
-    next if $text !~ /^\Q$string\E(\d+)/;
+    next if $text !~ /^\Q$string\E(\d+)/a;
     my $attachment_id = $1;
     my @lines         = split("\n", $text);
     if ($type == CMT_ATTACHMENT_CREATED) {
index 13fee1c115e3b60391e32006f0b5a2efb537c2f0..7cc4ce3805bdb2cbd79f36be845d49065589537b 100644 (file)
@@ -729,7 +729,7 @@ sub _update_old_charts {
         @declared_fields = map uc, (split /\||\r/, $1);
         print OUT "# fields: ", join('|', @out_fields), "\n";
       }
-      elsif (/^(\d+\|.*)/) {
+      elsif (/^(\d+\|.*)/a) {
         my @data = split(/\||\r/, $1);
         my %data;
         if (@data == @declared_fields) {
index 7ed341d8d0b17d064f937fb6c5b8cce3972aab9f..906b42c430ba1efac05603a10a6b7de59cdf344e 100644 (file)
@@ -747,7 +747,7 @@ sub have_vers {
 
     # If we come here, then the version is not a valid one.
     # We try to sanitize it.
-    if ($vnum =~ /^((\d+)(\.\d+)*)/) {
+    if ($vnum =~ /^((\d+)(\.\d+)*)/a) {
       $vnum = $1;
     }
   }
index 3b021b98331146b91285c76332f4f4c6edffcd4a..ea252c6eca47107bd8d764bef3c6ab68f7894251 100644 (file)
@@ -183,7 +183,7 @@ sub extension_requirement_packages {
   foreach my $file_set (@$file_sets) {
     my $file = shift @$file_set;
     my $name = require $file;
-    if ($name =~ /^\d+$/) {
+    if ($name =~ /^\d+$/a) {
       die install_string('extension_must_return_name',
         {file => $file, returned => $name});
     }
@@ -538,7 +538,7 @@ sub _sort_accept_language {
   my @qlanguages;
   my @languages;
   foreach (split /,/, $accept_language) {
-    if (m/([A-Za-z\-]+)(?:;q=(\d(?:\.\d+)))?/) {
+    if (m/([A-Za-z\-]+)(?:;q=(\d(?:\.\d+)))?/a) {
       my $lang   = $1;
       my $qvalue = $2;
       $qvalue = 1 if not defined $qvalue;
index 90c08996f7b854143629baa8d785bc94b69a80f1..a2efe5960914e9698e35faeda0c12ca76a6cac7d 100644 (file)
@@ -43,7 +43,7 @@ sub _mail_error_message {
   # Keep only the primary error line and drop any stack trace frames.
   ($message) = split /\n/, $message, 2;
 
-  $message =~ s/\s+at\s+\S+\s+line\s+\d+\.?\s*$//s;
+  $message =~ s/\s+at\s+\S+\s+line\s+(?a:\d+)\.?\s*$//s;
   $message =~ s/\s+called\s+at\s+.*$//s;
   $message =~ s/\s+/ /g;
   $message =~ s/^\s+|\s+$//g;
@@ -274,7 +274,7 @@ sub build_thread_marker {
     $sitespec = "-$path$sitespec";
   }
 
-  if ($sitespec =~ s/^([^:\/]+):(\d+)/$1/) {    # Remove port number, to relocate
+  if ($sitespec =~ s/^([^:\/]+):(\d+)/$1/a) {    # Remove port number, to relocate
     $sitespec = "-$2$sitespec";                  # Put the port number back in, before the '@'
   }
 
@@ -313,7 +313,7 @@ sub build_message_id {
     $sitespec = "-$path$sitespec";
   }
 
-  if ($sitespec =~ s/^([^:\/]+):(\d+)/$1/) {    # Remove port number, to relocate
+  if ($sitespec =~ s/^([^:\/]+):(\d+)/$1/a) {    # Remove port number, to relocate
     $sitespec = "-$2$sitespec";                  # Put the port number back in, before the '@'
   }
 
index db47b94ce64ae2b1721c3b037327e9480b0199fe..aae22a44c919028381a50f72f75a3fd765633020 100644 (file)
@@ -321,7 +321,7 @@ sub _parse_project {
   $self->debug("Reading Project: $directory");
 
   # Sometimes other files get into gnats directories.
-  @files = grep { basename($_) =~ /^\d+$/ } @files;
+  @files = grep { basename($_) =~ /^\d+$/a } @files;
   my @bugs;
   my $count = 1;
   my $total = scalar @files;
@@ -699,7 +699,7 @@ sub translate_value {
     # is longer than 32 characters, pull out the first thing that looks
     # like a version number.
     elsif (length($value) > LONG_VERSION_LENGTH) {
-      $value =~ s/^.+?\b(\d[\w\.]+)\b.+$/$1/;
+      $value =~ s/^.+?\b((?a:\d)[\w\.]+)\b.+$/$1/;
     }
   }
 
index ee49de84a4b338bc0bddc89e4bced66ff7a09bcb..15651f1456ab557b68d37c5a1b86263a0b6ff0a2 100644 (file)
@@ -803,7 +803,7 @@ sub _validate_time {
   # regexp verifies one or more digits, optionally followed by a period and
   # zero or more digits, OR we have a period followed by one or more digits
   # (allow negatives, though, so people can back out errors in time reporting)
-  if ($time !~ /^-?(?:\d+(?:\.\d*)?|\.\d+)$/) {
+  if ($time !~ /^-?(?:\d+(?:\.\d*)?|\.\d+)$/a) {
     ThrowUserError("number_not_numeric", {field => $field, num => "$time"});
   }
 
index d95ab5d552ad204552ffa3cf20b9624256b0cc56..6183b4be006d01cdac26d0a63184274ebfdc2467 100644 (file)
@@ -130,7 +130,7 @@ sub _check_seed {
 
   # If it looks like we were seeded with a 32-bit integer, warn the
   # user that they are making a dangerous, easily-crackable mistake.
-  elsif (length($seed) <= 10 and $seed =~ /^\d+$/) {
+  elsif (length($seed) <= 10 and $seed =~ /^\d+$/a) {
     warn "RNG seeded with a 32-bit integer, this is easy to crack";
   }
 }
index fcd6273abbba25b5479ce798ef549be139972b9f..53ece5113b3cb8ecf94a09c10ec3baea9ef21e66 100644 (file)
@@ -130,7 +130,7 @@ use constant NUMBER_REGEX => qr/
         \d+
     )?
     $
-/x;
+  /ax;
 
 # If you specify a search type in the boolean charts, this describes
 # which operator maps to which internal function here.
@@ -1542,7 +1542,7 @@ sub _special_parse_chfield {
   # chfieldto is supposed to be a relative date or a date of the form
   # YYYY-MM-DD, i.e. without the time appended to it. We append the
   # time ourselves so that the end date is correctly taken into account.
-  $date_to .= ' 23:59:59' if $date_to =~ /^\d{4}-\d{1,2}-\d{1,2}$/;
+  $date_to .= ' 23:59:59' if $date_to =~ /^\d{4}-\d{1,2}-\d{1,2}$/a;
 
   my $join_clause = new Bugzilla::Search::Clause('OR');
 
@@ -1579,11 +1579,11 @@ sub _special_parse_email {
   my ($self) = @_;
   my $params = $self->_params;
 
-  my @email_params = grep { $_ =~ /^email\d+$/ } keys %$params;
+  my @email_params = grep { $_ =~ /^email\d+$/a } keys %$params;
 
   my $clause = new Bugzilla::Search::Clause();
   foreach my $param (@email_params) {
-    $param =~ /(\d+)$/;
+    $param =~ /(\d+)$/a;
     my $id    = $1;
     my $email = trim($params->{"email$id"});
     next if !$email;
@@ -1685,20 +1685,20 @@ sub _boolean_charts {
   my $params     = $self->_params;
   my @param_list = keys %$params;
 
-  my @all_field_params = grep {/^field-?\d+/} @param_list;
-  my @chart_ids        = map  { /^field(-?\d+)/; $1 } @all_field_params;
+  my @all_field_params = grep {/^field-?\d+/a} @param_list;
+  my @chart_ids        = map  { /^field(-?\d+)/a; $1 } @all_field_params;
   @chart_ids = sort { $a <=> $b } uniq @chart_ids;
 
   my $clause = new Bugzilla::Search::Clause();
   foreach my $chart_id (@chart_ids) {
-    my @all_and = grep {/^field$chart_id-\d+/} @param_list;
-    my @and_ids = map  { /^field$chart_id-(\d+)/; $1 } @all_and;
+    my @all_and = grep {/^field$chart_id-\d+/a} @param_list;
+    my @and_ids = map  { /^field$chart_id-(\d+)/a; $1 } @all_and;
     @and_ids = sort { $a <=> $b } uniq @and_ids;
 
     my $and_clause = new Bugzilla::Search::Clause();
     foreach my $and_id (@and_ids) {
-      my @all_or = grep {/^field$chart_id-$and_id-\d+/} @param_list;
-      my @or_ids = map  { /^field$chart_id-$and_id-(\d+)/; $1 } @all_or;
+      my @all_or = grep {/^field$chart_id-$and_id-\d+/a} @param_list;
+      my @or_ids = map  { /^field$chart_id-$and_id-(\d+)/a; $1 } @all_or;
       @or_ids = sort { $a <=> $b } uniq @or_ids;
 
       my $or_clause = new Bugzilla::Search::Clause('OR');
@@ -1776,8 +1776,8 @@ sub _field_ids {
   my $params     = $self->_params;
   my @param_list = keys %$params;
 
-  my @field_params = grep {/^f\d+$/} @param_list;
-  my @field_ids    = map  { /(\d+)/; $1 } @field_params;
+  my @field_params = grep {/^f\d+$/a} @param_list;
+  my @field_ids    = map  { /(\d+)/a; $1 } @field_params;
   @field_ids = sort { $a <=> $b } @field_ids;
   return @field_ids;
 }
@@ -2126,7 +2126,7 @@ sub _timestamp_translate {
   my $value = $args->{value};
   my $dbh   = Bugzilla->dbh;
 
-  return if $value !~ /^(?:[\+\-]?\d+[hdwmy]s?|now)$/i;
+  return if $value !~ /^(?:[\+\-]?\d+[hdwmy]s?|now)$/ai;
 
   $value = SqlifyDate($value);
 
@@ -2171,7 +2171,7 @@ sub SqlifyDate {
     return sprintf("%4d-%02d-%02d 00:00:00", $year + 1900, $month + 1, $mday);
   }
 
-  if ($str =~ /^(-|\+)?(\d+)([hdwmy])(s?)$/i) {    # relative date
+  if ($str =~ /^(-|\+)?(\d+)([hdwmy])(s?)$/ai) {    # relative date
     my ($sign, $amount, $unit, $startof, $date) = ($1, $2, lc $3, lc $4, time);
     my ($sec, $min, $hour, $mday, $month, $year, $wday) = localtime($date);
     if ($sign && $sign eq '+') { $amount = -$amount; }
index 13f35c3f0e4be378bcd6dbfba78b9d1ae23a8c40..1087cdd06aeb03d78b184294e9c5b014050deb59 100644 (file)
@@ -553,7 +553,7 @@ sub _special_field_syntax {
   my ($word, $negate) = @_;
 
   # P1-5 Syntax
-  if ($word =~ m/^P(\d+)(?:-(\d+))?$/i) {
+  if ($word =~ m/^P(\d+)(?:-(\d+))?$/ai) {
     my ($p_start, $p_end) = ($1, $2);
     my $legal_priorities = get_legal_field_values('priority');
 
index 20cd93804d22e4bb2c027e91da541c7c7872674b..e7348090094231bb8a4150240508a46896dc7ab8 100644 (file)
@@ -186,7 +186,7 @@ sub rename_field_value {
     $query =~ s/\b$field=\Q$old\E\b/$field=$new/gi;
 
     # Fix boolean charts.
-    while ($query =~ /\bfield(\d+-\d+-\d+)=\Q$field\E\b/gi) {
+    while ($query =~ /\bfield(?a:(\d+-\d+-\d+))=\Q$field\E\b/gi) {
       my $chart_id = $1;
 
       # Note that this won't handle lists or substrings inside of
index 9348513dc2a8356461481701a6b4d18ae69dc49d..ed0ecf1dda5a14aec83b28af7e360cfcb5f3c4dd 100644 (file)
@@ -904,7 +904,7 @@ sub create {
        # so we do not allow it to happen. We only do this for logged-in users.
         $var =~ s/\\/\x{FF3C}/g if Bugzilla->user->id;
         $var =~ s/\"/\"\"/g;
-        if ($var !~ /^-?(\d+\.)?\d*$/) {
+        if ($var !~ /^-?(\d+\.)?\d*$/a) {
           $var = "\"$var\"";
         }
         return $var;
@@ -1086,7 +1086,7 @@ sub create {
           }
 
           my $version = BUGZILLA_VERSION;
-          $version =~ /^(\d+)\.(\d+)/;
+          $version =~ /^(\d+)\.(\d+)/a;
           if ($2 % 2 == 1) {
 
             # second number is odd; development version
index 239a2fd929319eaf1568f4d671de7d983276d1a5..503fa0bf2b30877bf984f6efaf539973ee444079 100644 (file)
@@ -60,7 +60,7 @@ sub get_notifications {
 
   # On which branch is the current installation running?
   my @current_version
-    = (BUGZILLA_VERSION =~ m/^(\d+)\.(\d+)(?:(rc|\.)(\d+))?\+?$/);
+    = (BUGZILLA_VERSION =~ m/^(\d+)\.(\d+)(?:(rc|\.)(\d+))?\+?$/a);
 
   my @release;
   if (Bugzilla->params->{'upgrade_notification'} eq 'development_snapshot') {
@@ -144,7 +144,7 @@ sub get_notifications {
   # Only notify the administrator if the latest version available
   # is newer than the current one.
   my @new_version
-    = ($release[0]->{'latest_ver'} =~ m/^(\d+)\.(\d+)(?:(rc|\.)(\d+))?\+?$/);
+    = ($release[0]->{'latest_ver'} =~ m/^(\d+)\.(\d+)(?:(rc|\.)(\d+))?\+?$/a);
 
   # We convert release candidates 'rc' to integers (rc ? 0 : 1) in order
   # to compare versions easily.
index 63faac0320c9490808cc3773888b9ba9eb2aca94..ed828c5bbce53db6182dff14ed0d7361d0fcf7fb 100644 (file)
@@ -437,7 +437,7 @@ sub _set_groups_to_object {
     # Go through the array, and turn items into group objects
     my @groups = ();
     foreach my $value (@{$changes->{$key}}) {
-      my $type  = $value =~ /^\d+$/ ? 'id' : 'name';
+      my $type  = $value =~ /^\d+$/a ? 'id' : 'name';
       my $group = Bugzilla::Group->new({$type => $value});
 
       if (!$group || !$user->can_bless($group->id)) {
@@ -1930,7 +1930,7 @@ sub match_field {
         # The field is a requestee field; in order for its name
         # to show up correctly on the confirmation page, we need
         # to find out the name of its flag type.
-        if ($field_name =~ /^requestee(_type)?-(\d+)$/) {
+        if ($field_name =~ /^requestee(_type)?-(\d+)$/a) {
           my $flag_type;
           if ($1) {
             require Bugzilla::FlagType;
@@ -2597,14 +2597,14 @@ sub validate_password_check {
   if ($complexity_level eq 'letters_numbers_specialchars') {
     return 'password_not_complex'
       if ($password !~ /[[:alpha:]]/
-      || $password !~ /\d/
+      || $password !~ /\d/a
       || $password !~ /[[:punct:]]/);
   }
   elsif ($complexity_level eq 'letters_numbers') {
     return 'password_not_complex'
       if ($password !~ /[[:lower:]]/
       || $password !~ /[[:upper:]]/
-      || $password !~ /\d/);
+      || $password !~ /\d/a);
   }
   elsif ($complexity_level eq 'mixed_letters') {
     return 'password_not_complex'
index 7e65e35c955ee5f11ac4fb128970bc029f009492..ac098f2c2c9be8390342bab0d164334c390c13cd 100644 (file)
@@ -361,11 +361,11 @@ sub is_ipv4 {
   my $ip = shift;
   return unless defined $ip;
 
-  my @octets = $ip =~ /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/;
+  my @octets = $ip =~ /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/a;
   return unless scalar(@octets) == 4;
 
   foreach my $octet (@octets) {
-    return unless ($octet >= 0 && $octet <= 255 && $octet !~ /^0\d{1,2}$/);
+    return unless ($octet >= 0 && $octet <= 255 && $octet !~ /^0\d{1,2}$/a);
   }
 
   # The IP address is valid and can now be detainted.
@@ -590,7 +590,7 @@ sub format_time {
   # If $format is not set, try to guess the correct date format.
   if (!$format) {
     if (!ref $date
-      && $date =~ /^(\d{4})[-\.](\d{2})[-\.](\d{2}) (\d{2}):(\d{2})(:(\d{2}))?$/)
+      && $date =~ /^(\d{4})[-\.](\d{2})[-\.](\d{2}) (\d{2}):(\d{2})(:(\d{2}))?$/a)
     {
       my $sec = $7;
       if (defined $sec) {
@@ -620,7 +620,7 @@ sub datetime_from {
   my @time;
 
   # Most dates will be in this format, avoid strptime's generic parser
-  if ($date =~ /^(\d{4})[\.-](\d{2})[\.-](\d{2})(?: (\d{2}):(\d{2}):(\d{2}))?$/) {
+  if ($date =~ /^(\d{4})[\.-](\d{2})[\.-](\d{2})(?: (\d{2}):(\d{2}):(\d{2}))?$/a) {
     @time = ($6, $5, $4, $3, $2 - 1, $1 - 1900, undef);
   }
   else {
@@ -782,8 +782,8 @@ sub validate_date {
   if ($ts) {
     $date2 = time2str("%Y-%m-%d", $ts);
 
-    $date  =~ s/(\d+)-0*(\d+?)-0*(\d+?)/$1-$2-$3/;
-    $date2 =~ s/(\d+)-0*(\d+?)-0*(\d+?)/$1-$2-$3/;
+    $date  =~ s/(\d+)-0*(\d+?)-0*(\d+?)/$1-$2-$3/a;
+    $date2 =~ s/(\d+)-0*(\d+?)-0*(\d+?)/$1-$2-$3/a;
   }
   my $ret = ($ts && $date eq $date2);
   return $ret ? 1 : 0;
@@ -797,7 +797,7 @@ sub validate_time {
   my $ts = str2time($time);
   if ($ts) {
     $time2 = time2str("%H:%M:%S", $ts);
-    if ($time =~ /^(\d{1,2}):(\d\d)(?::(\d\d))?$/) {
+    if ($time =~ /^(\d{1,2}):(\d\d)(?::(\d\d))?$/a) {
       $time = sprintf("%02d:%02d:%02d", $1, $2, $3 || 0);
     }
   }
index a96030265bd8b835fe9c741858bda1f764157435..27410371b70ab81d574e0b6b30ab6811ad75e3bd 100644 (file)
@@ -211,11 +211,11 @@ sub vers_cmp {
   my ($a, $b) = @_;
 
   # Remove leading zeroes - Bug 344661
-  $a =~ s/^0*(\d.+)/$1/;
-  $b =~ s/^0*(\d.+)/$1/;
+  $a =~ s/^0*(\d.+)/$1/a;
+  $b =~ s/^0*(\d.+)/$1/a;
 
-  my @A = ($a =~ /([-.]|\d+|[^-.\d]+)/g);
-  my @B = ($b =~ /([-.]|\d+|[^-.\d]+)/g);
+  my @A = ($a =~ /([-.]|\d+|[^-.\d]+)/ag);
+  my @B = ($b =~ /([-.]|\d+|[^-.\d]+)/ag);
 
   my ($A, $B);
   while (@A and @B) {
@@ -239,7 +239,7 @@ sub vers_cmp {
     elsif ($B eq '.') {
       return 1;
     }
-    elsif ($A =~ /^\d+$/ and $B =~ /^\d+$/) {
+    elsif ($A =~ /^\d+$/a and $B =~ /^\d+$/a) {
       if ($A =~ /^0/ || $B =~ /^0/) {
         return $A cmp $B if $A cmp $B;
       }
index b4834d964018a9f32465eaee4433b5f435ef19ef..c730c95b23de6d38ff78b2ec1a61999e7b70fda1 100644 (file)
@@ -399,7 +399,7 @@ sub get {
 
   # Cache permissions for bugs. This highly reduces the number of calls to the DB.
   # visible_bugs() is only able to handle bug IDs, so we have to skip aliases.
-  my @int = grep { $_ =~ /^\d+$/ } @$ids;
+  my @int = grep { $_ =~ /^\d+$/a } @$ids;
   Bugzilla->user->visible_bugs(\@int);
 
   foreach my $bug_id (@$ids) {
@@ -527,7 +527,7 @@ sub search {
   my %options = (fields => ['bug_id']);
 
   # Find the highest custom field id
-  my @field_ids     = grep(/^f(\d+)$/, keys %$match_params);
+  my @field_ids     = grep(/^f(\d+)$/a, keys %$match_params);
   my $last_field_id = @field_ids ? max @field_ids + 1 : 1;
 
   # Do special search types for certain fields.
index 2ccc3bbc1316b23f5ff7f0b499e8f6c6542de205..09a25a460e45e8c13bdcfd33ba8599e850ebc0f1 100644 (file)
@@ -512,7 +512,7 @@ sub _get_content_prefs {
   my @accept_types = split /,/, $self->cgi->http('accept') || '';
   my $order        = 0;
   for my $accept_type (@accept_types) {
-    my ($weight) = ($accept_type =~ /q=(\d\.\d+|\d+)/);
+    my ($weight) = ($accept_type =~ /q=(\d\.\d+|\d+)/a);
     my ($name)   = ($accept_type =~ m#(\S+/[^;]+)#);
     next unless $name;
     push @prefs, {name => $name, order => $order++};
index 01a75f5ac853995f62dcc49bd3f1ed78239cd319..b996e46f71eb50d4d69f2d19000f02701bd419c0 100644 (file)
@@ -134,7 +134,7 @@ sub _rest_resources {
         params => sub {
           my $value = $_[0];
           my $param = 'names';
-          $param = 'ids' if $value =~ /^\d+$/;
+          $param = 'ids' if $value =~ /^\d+$/a;
           return {$param => [$_[0]]};
         }
       }
index 4211edb196232773d548b4799a0cbc6ddffecd56..1f74122a41c6eadf0abfb4415ae6c180c1b0a2fb 100644 (file)
@@ -18,7 +18,7 @@ BEGIN {
 sub _rest_resources {
   return [
     # bug-id
-    qr{^/bug_user_last_visit/(\d+)$},
+    qr{^/bug_user_last_visit/(\d+)$}a,
     {
       GET => {
         method => 'get',
index f70e3cd5e28f136a4cd64aeb3088952cb4658e7e..4fca8237d8270f17f94cf43e50020feb1595df07 100644 (file)
@@ -25,7 +25,7 @@ sub _rest_resources {
       GET => {
         method => 'get',
         params => sub {
-          my $param = $_[0] =~ /^\d+$/ ? 'ids' : 'names';
+          my $param = $_[0] =~ /^\d+$/a ? 'ids' : 'names';
           return {$param => [$_[0]]};
         }
       }
index 2bc4ce6e2fe589e8cf0db66052c615eff5456294..30da5bf9253d1667685506fb90c7fc14f14e0965 100644 (file)
@@ -44,7 +44,7 @@ sub _rest_resources {
       PUT => {
         method => 'update',
         params => sub {
-          my $param = $_[0] =~ /^\d+$/ ? 'ids' : 'names';
+          my $param = $_[0] =~ /^\d+$/a ? 'ids' : 'names';
           return {$param => [$_[0]]};
         }
       }
index d2e2604df95c4152a3a5a1c348c94f0103dafae3..4a82b0b12bad2a3ff402d77bbf65eab696460bca 100644 (file)
@@ -30,7 +30,7 @@ sub _rest_resources {
       PUT => {
         method => 'update',
         params => sub {
-          my $param = $_[0] =~ /^\d+$/ ? 'ids' : 'names';
+          my $param = $_[0] =~ /^\d+$/a ? 'ids' : 'names';
           return {$param => [$_[0]]};
         }
       }
index 2df867e54dce0fbcbb8650a9930f537f7edd816b..471060db6aadddbe33b82a8e1342d9aec7fd35f2 100644 (file)
@@ -38,14 +38,14 @@ sub _rest_resources {
       GET => {
         method => 'get',
         params => sub {
-          my $param = $_[0] =~ /^\d+$/ ? 'ids' : 'names';
+          my $param = $_[0] =~ /^\d+$/a ? 'ids' : 'names';
           return {$param => [$_[0]]};
         }
       },
       PUT => {
         method => 'update',
         params => sub {
-          my $param = $_[0] =~ /^\d+$/ ? 'ids' : 'names';
+          my $param = $_[0] =~ /^\d+$/a ? 'ids' : 'names';
           return {$param => [$_[0]]};
         }
       }
index 6b817d88e770db9bc395250298a067db0b387f1a..704db4ea69674ca17d145284a38c66a94ed10249 100644 (file)
@@ -36,14 +36,14 @@ sub _rest_resources {
       GET => {
         method => 'get',
         params => sub {
-          my $param = $_[0] =~ /^\d+$/ ? 'ids' : 'names';
+          my $param = $_[0] =~ /^\d+$/a ? 'ids' : 'names';
           return {$param => [$_[0]]};
         }
       },
       PUT => {
         method => 'update',
         params => sub {
-          my $param = $_[0] =~ /^\d+$/ ? 'ids' : 'names';
+          my $param = $_[0] =~ /^\d+$/a ? 'ids' : 'names';
           return {$param => [$_[0]]};
         }
       }
index 9ff4f694486e68142fbfe55fcb528ade15e71167..a57df83361d4a58a578e1f8456f765fd5a5de451 100755 (executable)
@@ -136,7 +136,7 @@ if (my $last_list = $cgi->param('regetlastlist')) {
 # and order by, since relevance only exists when doing a fulltext search.
 my $fulltext = 0;
 if ($cgi->param('content')) { $fulltext = 1 }
-my @charts = map(/^field(\d-\d-\d)$/ ? $1 : (), $cgi->param());
+my @charts = map(/^field(\d-\d-\d)$/a ? $1 : (), $cgi->param());
 foreach my $chart (@charts) {
   if ($cgi->param("field$chart") eq 'content' && $cgi->param("value$chart")) {
     $fulltext = 1;
@@ -790,7 +790,7 @@ foreach my $row (@$data) {
   # Process certain values further (i.e. date format conversion).
   if ($bug->{'changeddate'}) {
     $bug->{'changeddate'}
-      =~ s/^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})$/$1-$2-$3 $4:$5:$6/;
+      =~ s/^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})$/$1-$2-$3 $4:$5:$6/a;
 
     $bug->{'changedtime'} = $bug->{'changeddate'};          # for iCalendar and Atom
     $bug->{'changeddate'} = DiffDate($bug->{'changeddate'});
index fb1fc9c78a3da6b0f623b4849f60d07919ac7e86..409ee1ab39f20b9a8d123a7edcdd8474a867dab9 100755 (executable)
--- a/chart.cgi
+++ b/chart.cgi
@@ -75,7 +75,7 @@ $vars->{'doc_section'} = 'using/reports-and-charts.html#charts';
 # encode it in the name, as "action-<action>". Some params even contain the
 # series_id they apply to (e.g. subscribe, unsubscribe).
 my @actions = grep(/^action-/, $cgi->param());
-if ($actions[0] && $actions[0] =~ /^action-([^\d]+)(\d*)$/) {
+if ($actions[0] && $actions[0] =~ /^action-(?a:([^\d]+)(\d*))$/) {
   $action    = $1;
   $series_id = $2 if $2;
 }
@@ -236,14 +236,14 @@ exit;
 
 # Find any selected series and return either the first or all of them.
 sub getAndValidateSeriesIDs {
-  my @series_ids = grep(/^\d+$/, $cgi->param("name"));
+  my @series_ids = grep(/^\d+$/a, $cgi->param("name"));
 
   return wantarray ? @series_ids : $series_ids[0];
 }
 
 # Return a list of IDs of all the lines selected in the UI.
 sub getSelectedLines {
-  my @ids = map { /^select(\d+)$/ ? $1 : () } $cgi->param();
+  my @ids = map { /^select(\d+)$/a ? $1 : () } $cgi->param();
 
   return @ids;
 }
index d77acb93af31e3fcf427a9556cbdbbf976212d89..560e790ee6460e7c421c39b463f7eceb67e06790 100755 (executable)
@@ -154,7 +154,7 @@ foreach my $table (@table_list) {
 
         # In MySQL, decimal cols can be too long.
         my $col_type = $col_info->{TYPE};
-        $col_type =~ /decimal\((\d+),(\d+)\)/;
+        $col_type =~ /decimal\((\d+),(\d+)\)/a;
         my ($precision, $decimals) = ($1, $2);
 
         # If it's longer than precision + decimal point
index 7c174806440d4cf27e2fb7b3473041065eecd2ed..a299f2386e88605968479c28bda3dc36113c1c4e 100755 (executable)
@@ -82,7 +82,7 @@ sub get_object {
   if (ref $_ eq 'HASH' && keys %$_) {
     @results = @{$class->match($_)};
   }
-  elsif (m/^\d+$/) {
+  elsif (m/^\d+$/a) {
     @results = ($class->new($_));
   }
   elsif (m/\w/i && grep { $_ eq 'name' } ($class->_get_db_columns)) {
index df68a942c6212d8acff3deee39f3cb3970e51825..9add6abcd9e12b00a4de831a9cdf3abfc07bfbb7 100755 (executable)
@@ -52,7 +52,7 @@ pod2usage(0) if $help;
 # Make sure accounts were specified on the command line and exist.
 my $old = $ARGV[0] || die "You must specify an old user account.\n";
 my $old_id;
-if ($old =~ /^id:(\d+)$/) {
+if ($old =~ /^id:(\d+)$/a) {
 
   # As the old user account may be a deleted one, we don't
   # check whether this user ID is valid or not.
@@ -75,7 +75,7 @@ else {
 
 my $new = $ARGV[1] || die "You must specify a new user account.\n";
 my $new_id;
-if ($new =~ /^id:(\d+)$/) {
+if ($new =~ /^id:(\d+)$/a) {
   $new_id = $1;
 
   # Make sure this user ID exists.
index bd34d3daf5ea59874e8a888e0b5ee20037f0699c..606460cf3126fc9605ca1cec17990080f9902961 100755 (executable)
@@ -33,7 +33,7 @@ my $bugnum  = $ARGV[0];
 my $changer = $ARGV[1];
 
 # Validate the bug number.
-if (!($bugnum =~ /^(\d+)$/)) {
+if (!($bugnum =~ /^(\d+)$/a)) {
   say STDERR "Bug number \"$bugnum\" not numeric.";
   usage();
 }
index 1b1b9b6e5f35886fca64252720f4a9400b4e6f5e..d9f7d1d45b4fa80f655d2583d8bfc371f34430b1 100755 (executable)
@@ -350,7 +350,7 @@ if ($action eq 'updategroupcontrols') {
   my @now_na        = ();
   my @now_mandatory = ();
   foreach my $f ($cgi->param()) {
-    if ($f =~ /^membercontrol_(\d+)$/) {
+    if ($f =~ /^membercontrol_(\d+)$/a) {
       my $id = $1;
       if ($cgi->param($f) == CONTROLMAPNA) {
         push @now_na, $id;
index eecda81bf7e2c97ce3396291b31493dfbc096639..4d6372fc89f379d1c3670dfa4b6427ecf4a1090f 100755 (executable)
@@ -81,7 +81,7 @@ sub parse_mail {
     {mail => $input_email, fields => \%fields});
 
   my $summary = $input_email->header('Subject');
-  if ($summary =~ /\[\S+ (\d+)\](.*)/i) {
+  if ($summary =~ /\[\S+ (?a:(\d+))\](.*)/i) {
     $fields{'bug_id'} = $1;
     $summary = trim($2);
   }
index 8201781f76a0384395feac251d67290e1ba14ace..b950ff2cedda5e4f5e283547346330e6f2aec04e 100644 (file)
@@ -426,7 +426,7 @@ sub email_in_before_parse {
   my $subject = $args->{mail}->header('Subject');
 
   # Correctly extract the bug ID from email subjects of the form [Bug comp/NNN].
-  if ($subject =~ /\[.*(\d+)\].*/) {
+  if ($subject =~ /\[.*(\d+)\].*/a) {
     $args->{fields}->{bug_id} = $1;
   }
 }
index 6a380929894a0fa6dd56100474bd00777503ecb9..bf805a2b18ef692bcc1168b51f42050870a44c31 100644 (file)
@@ -23,7 +23,7 @@ sub should_handle {
   # BitBucket issues have the form of
   # bitbucket.org/user/project/issue/1234
   return (lc($uri->authority) eq "bitbucket.org"
-      && $uri->path =~ m|[^/]+/[^/]+/issue/\d+|i) ? 1 : 0;
+      && $uri->path =~ m|[^/]+/[^/]+/issue/\d+|ai) ? 1 : 0;
 }
 
 sub _check_value {
@@ -31,7 +31,7 @@ sub _check_value {
 
   my $uri = $class->SUPER::_check_value(@_);
 
-  my ($path) = $uri->path =~ m|([^/]+/[^/]+/issue/\d+)|i;
+  my ($path) = $uri->path =~ m|([^/]+/[^/]+/issue/\d+)|ai;
   $uri = new URI("https://bitbucket.org/$path");
 
   return $uri;
index e326d8222bf1fb016a6332b4cc2fe08c2da0fcb9..12b42325b69b45f301c0a6431cb87eddac4e444e 100644 (file)
@@ -24,7 +24,7 @@ sub should_handle {
   #   https://bugs.php.net/bug.php?id=1234
   return (lc($uri->authority) eq 'bugs.php.net'
       and $uri->path =~ m|/bug\.php$|
-      and $uri->query_param('id') =~ /^\d+$/) ? 1 : 0;
+      and $uri->query_param('id') =~ /^\d+$/a) ? 1 : 0;
 }
 
 sub _check_value {
index d23675d6e7719ebd05d109b55ff4b944ee325778..227d8f9172da6174d2594b3fd61a53ba64530b37 100644 (file)
@@ -23,7 +23,7 @@ sub should_handle {
   # RT URLs can look like various things:
   #   http://example.com/rt/Ticket/Display.html?id=1234
   #   https://example.com/Public/Bug/Display.html?id=1234
-  return ($uri->path =~ m|/Display\.html$| and $uri->query_param('id') =~ /^\d+$/)
+  return ($uri->path =~ m|/Display\.html$| and $uri->query_param('id') =~ /^\d+$/a)
     ? 1
     : 0;
 }
index e21ba2e569d91d2b5d1b6e7fb8240e7f55922c54..bddc5c4f530f5c1f3a8f609750d9c63e45e1c04f 100644 (file)
@@ -19,7 +19,7 @@ use base qw(Bugzilla::BugUrl);
 
 sub should_handle {
   my ($class, $uri) = @_;
-  return ($uri->path =~ m|/issues/\d+$|) ? 1 : 0;
+  return ($uri->path =~ m|/issues/\d+$|a) ? 1 : 0;
 }
 
 sub _check_value {
index 1da4c4c9eac98b24444b48bf6258f58fae28c931..6eeccad7631bb585263c563d7391dcea618f8e19 100644 (file)
@@ -19,7 +19,7 @@ use base qw(Bugzilla::BugUrl);
 
 sub should_handle {
   my ($class, $uri) = @_;
-  return ($uri->path =~ m|/r/\d+/?$|) ? 1 : 0;
+  return ($uri->path =~ m|/r/\d+/?$|a) ? 1 : 0;
 }
 
 sub _check_value {
index 7febde23741280765f3b5474ba32b2179dbe18bf..a4338d462125d3f3ec86a9ddee0e0649102bc407 100644 (file)
@@ -20,7 +20,7 @@ use base qw(Bugzilla::BugUrl);
 sub should_handle {
   my ($class, $uri) = @_;
   return ($uri->authority =~ /\.appspot\.com$/i
-      and $uri->path =~ m#^/\d+(?:/|/show)?$#) ? 1 : 0;
+      and $uri->path =~ m#^/\d+(?:/|/show)?$#a) ? 1 : 0;
 }
 
 sub _check_value {
@@ -32,7 +32,7 @@ sub _check_value {
   #   http(s)://example.appspot.com/1234
   #   http(s)://example.appspot.com/1234/
   #   http(s)://example.appspot.com/1234/show
-  if ($uri->path =~ m#^/(\d+)(?:/|/show)$#) {
+  if ($uri->path =~ m#^/(\d+)(?:/|/show)$#a) {
 
     # This is the shortest standard URL form for Rietveld issues,
     # and so we reduce all URLs to this.
index 69fa10a9d98d3274344f0dcb739b3edb05b1d82a..b744aaf7109ec8070e65884b07c03c3841edb372 100644 (file)
@@ -19,7 +19,7 @@ use base qw(Bugzilla::BugUrl);
 
 sub should_handle {
   my ($class, $uri) = @_;
-  return ($uri->as_string =~ m|/bugs/(index\.php)?\?\d+$|) ? 1 : 0;
+  return ($uri->as_string =~ m|/bugs/(index\.php)?\?\d+$|a) ? 1 : 0;
 }
 
 sub _check_value {
index 42e6d99ca029d0f30edcbd7a8c08a290fdcc1778..24c1604cae9013647237022e52700b58de2364d0 100644 (file)
@@ -24,8 +24,8 @@ sub should_handle {
   #   http(s)://forum.winehq.org/viewtopic.php?f=1234&t=1234
   return (lc($uri->authority) eq 'forum.winehq.org'
     and $uri->path =~ m|^/viewtopic\.php$|
-    and $uri->query_param('f') =~ /^\d+$/
-    and $uri->query_param('t') =~ /^\d+$/) ? 1 : 0;
+    and $uri->query_param('f') =~ /^\d+$/a
+    and $uri->query_param('t') =~ /^\d+$/a) ? 1 : 0;
 }
 
 sub _check_value {
index f8674837a64ffa448a433de4de2032e2a09df313..5ad608cef582bf6b95caabb16e67a56231e97a43 100644 (file)
@@ -508,7 +508,7 @@ sub _update_votes {
   # are submitted in form fields in which the field names are the bug
   # IDs and the field values are the number of votes.
 
-  my @buglist = grep {/^\d+$/} keys %$input;
+  my @buglist = grep {/^\d+$/a} keys %$input;
   my (%bugs, %votes);
 
   # If no bugs are in the buglist, let's make sure the user gets notified
index 3be5bd2b72e38387e4df18370f80d46edfada70d..c59f6338c7a78683e573f44c707cd2594fa5fbe7 100755 (executable)
@@ -516,12 +516,12 @@ sub process_bug {
     # to the wrong attachment. Since the new attachment ID is unknown yet
     # let's strip it out for now. We will make a comment with the right ID
     # later
-    $data =~ s/Created an attachment \(id=\d+\)/Created an attachment/g;
+    $data =~ s/Created an attachment \(id=\d+\)/Created an attachment/ag;
 
     # Same goes for bug #'s Since we don't know if the referenced bug
     # is also being moved, lets make sure they know it means a different
     # bugzilla.
-    $data =~ s/([Bb]ugs?\s*\#?\s*(\d+))/$url$2/g;
+    $data =~ s/([Bb]ugs?\s*\#?\s*(\d+))/$url$2/ag;
 
     # Keep the original commenter if possible, else we will fall back
     # to the exporter account.
index 17ed5a1ee5ef5567cd625f32111359cf31f73d20..143f87c378a44726900e8a744bf30467076bcf4d 100755 (executable)
@@ -315,7 +315,7 @@ if (defined $cgi->param('id')) {
 
 my %is_private;
 foreach my $field (grep(/^defined_isprivate/, $cgi->param())) {
-  if ($field =~ /(\d+)$/) {
+  if ($field =~ /(\d+)$/a) {
     my $comment_id = $1;
     $is_private{$comment_id} = $cgi->param("isprivate_$comment_id");
   }
index d7c217788eaa14e0f6afddaed23158947b8a2b3a..031e8cb556a0356cb754e55fc34f99bb15743df9 100755 (executable)
--- a/query.cgi
+++ b/query.cgi
@@ -115,7 +115,7 @@ sub PrefillForm {
   # search or from an old link on the web somewhere) then convert them
   # to the new "custom search" format so that the form is populated
   # properly.
-  my $any_boolean_charts = grep {/^field-?\d+/} $buf->param();
+  my $any_boolean_charts = grep {/^field-?\d+/a} $buf->param();
   if ($any_boolean_charts) {
     my $search = new Bugzilla::Search(params => scalar $buf->Vars);
     $search->boolean_charts_to_custom_search($buf);
@@ -132,14 +132,14 @@ sub PrefillForm {
 
     # If the name is a single letter followed by numbers, it's part
     # of Custom Search. We store these as an array of hashes.
-    if ($name =~ /^([[:lower:]])(\d+)$/) {
+    if ($name =~ /^([[:lower:]])(\d+)$/a) {
       $default{'custom_search'}->[$2]->{$1} = $values[0];
     }
 
     # If the name ends in a number (which it does for the fields which
     # are part of the email searching), we use the array
     # positions to show the defaults for that number field.
-    elsif ($name =~ /^(\w+)(\d)$/) {
+    elsif ($name =~ /^(\w+)(?a:(\d))$/) {
       $default{$1}->[$2] = $values[0];
     }
     else {
index 6aebe20dc2e81c90427f7bdfa8ac21f83fb72cba..5b6ed32d96cb6436f0435016026359c170ace1fa 100755 (executable)
@@ -219,7 +219,7 @@ foreach my $result (@$results) {
       for my $row (@rows) {
         $data{$tbl}{$col}{$row}++;
         $names{"row"}{$row}++;
-        $row_isnumeric &&= ($row =~ /^-?\d+(\.\d+)?$/o);
+        $row_isnumeric &&= ($row =~ /^-?\d+(\.\d+)?$/ao);
         if ($formatparam eq "table") {
           if (!$in_row_total{$row}) {
             $data{$tbl}{'-total-'}{$row}++;
@@ -239,10 +239,10 @@ foreach my $result (@$results) {
         }
       }
       $names{"col"}{$col}++;
-      $col_isnumeric &&= ($col =~ /^-?\d+(\.\d+)?$/o);
+      $col_isnumeric &&= ($col =~ /^-?\d+(\.\d+)?$/ao);
     }
     $names{"tbl"}{$tbl}++;
-    $tbl_isnumeric &&= ($tbl =~ /^-?\d+(\.\d+)?$/o);
+    $tbl_isnumeric &&= ($tbl =~ /^-?\d+(\.\d+)?$/ao);
     if ($formatparam eq "table") {
       $data{$tbl}{'-total-'}{'-total-'}++;
     }
index 66873e40bbf0ce63ffb15563b1758df91d6d3803..c84f1a9450db2e3536b7537e007496148a87c9be 100755 (executable)
@@ -171,7 +171,7 @@ sub generate_chart {
 
     my @line = split /\|/;
     my $date = $line[0];
-    my ($yy, $mm, $dd) = $date =~ /^\d{2}(\d{2})(\d{2})(\d{2})$/;
+    my ($yy, $mm, $dd) = $date =~ /^\d{2}(\d{2})(\d{2})(\d{2})$/a;
     push @{$data{DATE}}, "$mm/$dd/$yy";
 
     for my $i (1 .. $#fields) {
index 2839abbc07dcea187cf8f587ce3b94e51c549a0e..d67e683aac8441cf654ba5ed732b2d4a00e53a8d 100755 (executable)
@@ -54,12 +54,12 @@ if ($single) {
   push @bugs, Bugzilla::Bug->check({id => $id, cache => 1});
   if (defined $cgi->param('mark')) {
     foreach my $range (split ',', $cgi->param('mark')) {
-      if ($range =~ /^(\d+)-(\d+)$/) {
+      if ($range =~ /^(\d+)-(\d+)$/a) {
         foreach my $i ($1 .. $2) {
           $marks{$i} = 1;
         }
       }
-      elsif ($range =~ /^(\d+)$/) {
+      elsif ($range =~ /^(\d+)$/a) {
         $marks{$1} = 1;
       }
     }
index bf9d560e87209775e657b01ddd3d78174e9dfb93..3e495f374cb5fef972839cb293730ed120148fec 100755 (executable)
@@ -57,7 +57,7 @@ sub CreateImagemap {
     }
 
     if ($line
-      =~ /^rectangle \((\d+),(\d+)\) \((\d+),(\d+)\) (http[^ ]*) (\d+)(?:\\n.*)?$/)
+      =~ /^rectangle \((\d+),(\d+)\) \((\d+),(\d+)\) (http[^ ]*) (\d+)(?:\\n.*)?$/a)
     {
       my ($leftx, $rightx, $topy, $bottomy, $url, $bugid) = ($1, $3, $2, $4, $5, $6);
 
index c4542b42eb2b3d465049c3f523fc143894eabc8a..d23fbfef24a455da94e9ba0fa284e715aba864a3 100755 (executable)
@@ -39,7 +39,7 @@ my $id  = $bug->id;
 
 local our $hide_resolved = $cgi->param('hide_resolved') ? 1 : 0;
 local our $maxdepth = $cgi->param('maxdepth') || 0;
-if ($maxdepth !~ /^\d+$/) {
+if ($maxdepth !~ /^\d+$/a) {
   $maxdepth = 0;
 }
 
index 3f8784618d545ff307bbe45b1a267ad89399bfa4..a38533a236dfa2a6a39aa97832b5d4c7db77a458 100755 (executable)
@@ -46,7 +46,7 @@ if (!ON_WINDOWS) {
   foreach my $pscmd (@pscmds) {
     open PH, '-|', "$pscmd 2>/dev/null";
     while (my $line = <PH>) {
-      if ($line =~ /^(?:\S*\/)?(?:httpd|apache?)2?\s+(\d+)$/) {
+      if ($line =~ /^(?:\S*\/)?(?:httpd|apache?)2?\s+(?a:(\d+))$/) {
         $sgid = $1 if $1 > $sgid;
       }
     }
@@ -57,7 +57,7 @@ if (!ON_WINDOWS) {
 # Determine the numeric GID of $webservergroup
 my $webgroupnum    = 0;
 my $webservergroup = Bugzilla->localconfig->{webservergroup};
-if ($webservergroup =~ /^(\d+)$/) {
+if ($webservergroup =~ /^(\d+)$/a) {
   $webgroupnum = $1;
 }
 else {
@@ -239,7 +239,7 @@ sub fetch {
   }
   else {
     my ($host, $port, $file) = ('', 80, '');
-    if ($url =~ m#^http://([^:]+):(\d+)(/.*)#i) {
+    if ($url =~ m#^http://([^:]+):(?a:(\d+))(/.*)#i) {
       ($host, $port, $file) = ($1, $2, $3);
     }
     elsif ($url =~ m#^http://([^/]+)(/.*)#i) {
@@ -268,8 +268,8 @@ sub fetch {
         $content .= $line;
       }
 
-      my ($status) = $header =~ m#^HTTP/\d+\.\d+ (\d+)#;
-      $rtn = (($status =~ /^2\d\d/) ? $content : undef);
+      my ($status) = $header =~ m#^HTTP/(?a:\d+\.\d+) (?a:(\d+))#;
+      $rtn = (($status =~ /^2\d\d/a) ? $content : undef);
     }
   }
   return ($rtn);
index 9faada1c204f09d61064fe4dbf7ea686d603c3c9..f41d985eae30a857023a2e098e62be7bb7f93b80 100755 (executable)
@@ -349,7 +349,7 @@ sub SaveEmail {
 
   # Remove any bug ids the user no longer wants to ignore
   foreach my $key (grep(/^remove_ignored_bug_/, $cgi->param)) {
-    my ($bug_id) = $key =~ /(\d+)$/;
+    my ($bug_id) = $key =~ /(\d+)$/a;
     delete $ignored_bugs{$bug_id};
   }
 
index b28397c86b678d32b44a3a9118420ea8a0b6bca0..3c7877662cf69561a33037e9b476ed75c9ec0780 100755 (executable)
--- a/whine.pl
+++ b/whine.pl
@@ -133,7 +133,7 @@ while (my ($schedule_id, $day, $time) = $sched_h->fetchrow_array) {
   if (&check_today($day)) {
 
     # Values that are not entirely numeric are intervals, like "30min"
-    if ($time !~ /^\d+$/) {
+    if ($time !~ /^\d+$/a) {
 
       # set it to now
       $sth = $dbh->prepare(
@@ -176,7 +176,7 @@ while (my ($schedule_id, $day, $time) = $sched_h->fetchrow_array) {
 
     # If configured for a particular time, set it to that, otherwise
     # midnight
-    my $target_time = ($time =~ /^\d+$/) ? $time : 0;
+    my $target_time = ($time =~ /^\d+$/a) ? $time : 0;
 
     my $run_next
       = $dbh->sql_date_math(
@@ -540,11 +540,11 @@ sub reset_timer {
   # If the schedule is to run today, and it runs many times per day,
   # it shall be set to run immediately.
   $run_today = &check_today($run_day);
-  if (($run_today) && ($run_time !~ /^\d+$/)) {
+  if (($run_today) && ($run_time !~ /^\d+$/a)) {
 
     # The default of 60 catches any bad value
     my $minute_interval = 60;
-    if ($run_time =~ /^(\d+)min$/i) {
+    if ($run_time =~ /^(\d+)min$/ai) {
       $minute_interval = $1;
     }
 
@@ -563,7 +563,7 @@ sub reset_timer {
     $minute_offset = 0;
 
     # Set the target time if it's a specific hour
-    my $target_time = ($run_time =~ /^\d+$/) ? $run_time : 0;
+    my $target_time = ($run_time =~ /^\d+$/a) ? $run_time : 0;
 
     my $nextdate = &get_next_date($run_day);
     my $run_next
@@ -647,7 +647,7 @@ sub get_next_date {
       $add_days = 2;
     }
   }
-  elsif ($day !~ /^\d+$/) {        # A specific day of the week
+  elsif ($day !~ /^\d+$/a) {        # A specific day of the week
         # The default is used if there is a bad value in the database, in
         # which case we mark it to a less-popular day (Sunday)
     my $day_num = 0;
index 2ccaab73538946da1e59bac67dd42603d028a6ef..9ba76a80b669c6fb77f927dd60871742daeb0736 100644 (file)
@@ -466,7 +466,7 @@ sub _translate_value {
   }
 
   # Sanity check to make sure that none of the <> stuff was left in.
-  if ($value =~ /<\d/) {
+  if ($value =~ /<\d/a) {
     die $self->name . ": value untranslated: $value\n";
   }
   return $value;
@@ -485,7 +485,7 @@ sub _translate_value_for_bug {
   $value =~ s/<$number-reporter>/$reporter/g;
   if ($value =~ /<$number-bug_group>/) {
     my @bug_groups = map { $_->name } @{$bug->groups_in};
-    @bug_groups = grep { $_ =~ /^\d+-group-/ } @bug_groups;
+    @bug_groups = grep { $_ =~ /^\d+-group-/a } @bug_groups;
     my $group = $bug_groups[0];
     $value =~ s/<$number-bug_group>/$group/g;
   }