diff options
19 files changed, 825 insertions, 27 deletions
diff --git a/duplicates.cgi b/duplicates.cgi index 1a3c08a9f..64a3f7ab3 100755 --- a/duplicates.cgi +++ b/duplicates.cgi @@ -74,7 +74,7 @@ my $sortby = formvalue("sortby"); my $changedsince = formvalue("changedsince", 7); my $maxrows = formvalue("maxrows", 100); my $openonly = formvalue("openonly"); -my $reverse = formvalue("reverse"); +my $reverse = formvalue("reverse") ? 1 : 0; my $product = formvalue("product"); my $sortvisible = formvalue("sortvisible"); my @buglist = (split(/[:,]/, formvalue("bug_id"))); @@ -159,8 +159,14 @@ if (!tie(%before, 'AnyDBM_File', "data/duplicates/dupes$whenever", $dobefore = 1; } +my $origmaxrows = $maxrows; detaint_natural($maxrows) - || ThrowUserError("invalid_maxrows", { maxrows => $maxrows}); + || ThrowUserError("invalid_maxrows", { maxrows => $origmaxrows}); + +my $origchangedsince = $changedsince; +detaint_natural($changedsince) + || ThrowUserError("invalid_changedsince", + { changedsince => $origchangedsince }); my @bugs; my @bug_ids; diff --git a/t/008filter.t b/t/008filter.t new file mode 100644 index 000000000..10d7fc62c --- /dev/null +++ b/t/008filter.t @@ -0,0 +1,182 @@ +# -*- Mode: perl; indent-tabs-mode: nil -*- +# +# The contents of this file are subject to the Mozilla Public +# License Version 1.1 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the License for the specific language governing +# rights and limitations under the License. +# +# The Original Code are the Bugzilla tests. +# +# The Initial Developer of the Original Code is Jacob Steenhagen. +# Portions created by Jacob Steenhagen are +# Copyright (C) 2001 Jacob Steenhagen. All +# Rights Reserved. +# +# Contributor(s): Gervase Markham <gerv@gerv.net> + +################# +#Bugzilla Test 8# +#####filter###### + +# This test scans all our templates for every directive. Having eliminated +# those which cannot possibly cause XSS problems, it then checks the rest +# against the safe list stored in the filterexceptions.pl file. + +# Sample exploit code: '>"><script>alert('Oh dear...')</script> + +use strict; +use lib 't'; + +use vars qw(%safe); + +use Support::Templates; +use File::Spec 0.82; +use Test::More tests => $Support::Templates::num_actual_files; +use Cwd; + +# Undefine the record separator so we can read in whole files at once +my $oldrecsep = $/; +$/ = undef; +my $topdir = cwd; + +foreach my $path (@Support::Templates::include_paths) { + $path =~ m|template/([^/]+)/|; + my $lang = $1; + chdir $topdir; # absolute path + my @testitems = Support::Templates::find_actual_files($path); + + next unless @testitems; + + # Some people require this, others don't. No-one knows why. + chdir $path; # relative path + + # We load a %safe list of acceptable exceptions. + if (!-r "filterexceptions.pl") { + ok(0, "$path has templates but no filterexceptions.pl file. --ERROR"); + next; + } + else { + do "filterexceptions.pl"; + } + + # We preprocess the %safe hash of lists into a hash of hashes. This allows + # us to flag which members were not found, and report that as a warning, + # thereby keeping the lists clean. + foreach my $file (keys %safe) { + my $list = $safe{$file}; + $safe{$file} = {}; + foreach my $directive (@$list) { + $safe{$file}{$directive} = 0; + } + } + + foreach my $file (@testitems) { + # There are some files we don't check, because there is no need to + # filter their contents due to their content-type. + if ($file =~ /\.(txt|png)\.tmpl$/) { + ok(1, "($lang) $file is filter-safe"); + next; + } + + # Read the entire file into a string + open (FILE, "<$file") || die "Can't open $file: $!\n"; + my $slurp = <FILE>; + close (FILE); + + my @unfiltered; + + # /g means we execute this loop for every match + # /s means we ignore linefeeds in the regexp matches + while ($slurp =~ /\[%(.*?)%\]/gs) { + my $directive = $1; + + my @lineno = ($` =~ m/\n/gs); + my $lineno = scalar(@lineno) + 1; + + # Comments + next if $directive =~ /^[+-]?#/; + + # Remove any leading/trailing + or - and whitespace. + $directive =~ s/^[+-]?\s*//; + $directive =~ s/\s*[+-]?$//; + + # Directives + next if $directive =~ /^(IF|END|UNLESS|FOREACH|PROCESS|INCLUDE| + BLOCK|USE|ELSE|NEXT|LAST|DEFAULT|FLUSH| + ELSIF|SET|SWITCH|CASE)/x; + + # Simple assignments + next if $directive =~ /^[\w\.\$]+\s+=\s+/; + + # Conditional literals with either sort of quotes + # There must be no $ in the string for it to be a literal + next if $directive =~ /^(["'])[^\$]*[^\\]\1/; + + # Special values always used for numbers + next if $directive =~ /^[ijkn]$/; + next if $directive =~ /^count$/; + + # Params + next if $directive =~ /^Param\(/; + + # Other functions guaranteed to return OK output + next if $directive =~ /^(time2str|GetBugLink)\(/; + + # Safe Template Toolkit virtual methods + next if $directive =~ /\.(size)$/; + + # Special Template Toolkit loop variable + next if $directive =~ /^loop\.(index|count)$/; + + # Things which are already filtered + # Note: If a single directive prints two things, and only one is + # filtered, we may not catch that case. + next if $directive =~ /FILTER\ (html|csv|js|url_quote|quoteUrls| + time|uri|xml)/x; + + # Exclude those on the nofilter list + if (defined($safe{$file}{$directive})) { + $safe{$file}{$directive}++; + next; + }; + + # This intentionally makes no effort to eliminate duplicates; to do + # so would merely make it more likely that the user would not + # escape all instances when attempting to correct an error. + push(@unfiltered, "$lineno:$directive"); + } + + my $fullpath = File::Spec->catfile($path, $file); + + if (@unfiltered) { + my $uflist = join("\n ", @unfiltered); + ok(0, "($lang) $fullpath has unfiltered directives:\n $uflist\n--ERROR"); + } + else { + # Find any members of the exclusion list which were not found + my @notfound; + foreach my $directive (keys %{$safe{$file}}) { + push(@notfound, $directive) if ($safe{$file}{$directive} == 0); + } + + if (@notfound) { + my $nflist = join("\n ", @notfound); + ok(0, "($lang) $fullpath - FEL has extra members:\n $nflist\n" . + "--WARNING"); + } + else { + # Don't use the full path here - it's too long and unwieldy. + ok(1, "($lang) $file is filter-safe"); + } + } + } +} + +$/ = $oldrecsep; + +exit 0; diff --git a/template/en/default/account/auth/login.html.tmpl b/template/en/default/account/auth/login.html.tmpl index 6dbd6531f..f342b1791 100644 --- a/template/en/default/account/auth/login.html.tmpl +++ b/template/en/default/account/auth/login.html.tmpl @@ -34,7 +34,7 @@ I need a legitimate login and password to continue. </p> -<form action="[% target %]" method="POST"> +<form action="[% target FILTER html %]" method="POST"> <table> <tr> <td align="right"> diff --git a/template/en/default/attachment/edit.html.tmpl b/template/en/default/attachment/edit.html.tmpl index 57d99f766..7cd682cd5 100644 --- a/template/en/default/attachment/edit.html.tmpl +++ b/template/en/default/attachment/edit.html.tmpl @@ -51,7 +51,7 @@ // If this is a plaintext document, remove cruft that Mozilla adds // because it treats it as an HTML document with a big PRE section. // http://bugzilla.mozilla.org/show_bug.cgi?id=86012 - var contentType = '[% contenttype %]'; + var contentType = '[% contenttype FILTER js %]'; if ( contentType == 'text/plain' ) { theContent = theContent.replace( /^<html><head\/?><body><pre>/i , "" ); diff --git a/template/en/default/bug/create/create-guided.html.tmpl b/template/en/default/bug/create/create-guided.html.tmpl index a716ddca6..7ab7436a7 100644 --- a/template/en/default/bug/create/create-guided.html.tmpl +++ b/template/en/default/bug/create/create-guided.html.tmpl @@ -211,8 +211,10 @@ function PutDescription() { <form method="post" action="post_bug.cgi"> <input type="hidden" name="format" value="guided"> <input type="hidden" name="assigned_to" value=""> - <input type="hidden" name="priority" value="[% default.priority %]"> - <input type="hidden" name="version" value="[% default.version %]"> + <input type="hidden" name="priority" + value="[% default.priority FILTER html %]"> + <input type="hidden" name="version" + value="[% default.version FILTER html %]"> <table valign="top" cellpadding="5" cellspacing="5" border="0"> diff --git a/template/en/default/bug/create/create.html.tmpl b/template/en/default/bug/create/create.html.tmpl index c59cd3a70..fcc894e1e 100644 --- a/template/en/default/bug/create/create.html.tmpl +++ b/template/en/default/bug/create/create.html.tmpl @@ -107,7 +107,8 @@ [% sel = { description => 'Priority', name => 'priority' } %] [% INCLUDE select %] [% ELSE %] - <input type="hidden" name="priority" value="[% default.priority %]"> + <input type="hidden" name="priority" + value="[% default.priority FILTER html %]"> [% END %] [% sel = { description => 'Severity', name => 'bug_severity' } %] diff --git a/template/en/default/bug/create/make-template.html.tmpl b/template/en/default/bug/create/make-template.html.tmpl index 1e2495ff8..958d183cc 100644 --- a/template/en/default/bug/create/make-template.html.tmpl +++ b/template/en/default/bug/create/make-template.html.tmpl @@ -25,7 +25,7 @@ %] <p> -If you bookmark <a href="enter_bug.cgi?[% url %]">this link</a>, +If you bookmark <a href="enter_bug.cgi?[% url FILTER html %]">this link</a>, going to the bookmark will bring up the enter bug page with the fields initialized as you've requested. </p> diff --git a/template/en/default/bug/show-multiple.html.tmpl b/template/en/default/bug/show-multiple.html.tmpl index a5cdc4dc8..41d824eb3 100644 --- a/template/en/default/bug/show-multiple.html.tmpl +++ b/template/en/default/bug/show-multiple.html.tmpl @@ -106,7 +106,8 @@ <tr> <td colspan="4"> <b>URL:</b> - <a href="[% bug.bug_file_loc %]">[% bug.bug_file_loc FILTER html %]</a> + <a href="[% bug.bug_file_loc FILTER html %]"> + [% bug.bug_file_loc FILTER html %]</a> </tr> <tr> diff --git a/template/en/default/filterexceptions.pl b/template/en/default/filterexceptions.pl new file mode 100644 index 000000000..b462b7bcc --- /dev/null +++ b/template/en/default/filterexceptions.pl @@ -0,0 +1,597 @@ +# -*- Mode: perl; indent-tabs-mode: nil -*- +# +# The contents of this file are subject to the Mozilla Public +# License Version 1.1 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the License for the specific language governing +# rights and limitations under the License. +# +# The Original Code are the Bugzilla tests. +# +# The Initial Developer of the Original Code is Jacob Steenhagen. +# Portions created by Jacob Steenhagen are +# Copyright (C) 2001 Jacob Steenhagen. All +# Rights Reserved. +# +# Contributor(s): Gervase Markham <gerv@gerv.net> + +# Important! The following classes of directives are excluded in the test, +# and so do not need to be added here. Doing so will cause warnings. +# See 008filter.t for more details. +# +# Comments - [%#... +# Directives - [% IF|ELSE|UNLESS|FOREACH... +# Assignments - [% foo = ... +# Simple literals - [% " selected" ... +# Values always used for numbers - [% (i|j|k|n|count) %] +# Params - [% Param(... +# Safe functions - [% (time2str|GetBugLink)... +# Safe vmethods - [% foo.size %] +# TT loop variables - [% loop.count %] +# Already-filtered stuff - [% wibble FILTER html %] +# where the filter is one of html|csv|js|url_quote|quoteUrls|time|uri|xml + +# Key: +# +# "#": directive should be filtered, but not doing so is not a security hole +# The plan is to come back and add filtering for all those marked "#" after +# the security release. +# +# "# Email": as above; but noting that it's an email address. +# Other sorts of comments denote cleanups noticed while doing this work; +# they should be fixed in the very short term. + +%::safe = ( + +'sidebar.xul.tmpl' => [ + 'template_version', +], + +'flag/list.html.tmpl' => [ + 'flag.id', + 'flag.status', + 'type.id', +], + +'search/boolean-charts.html.tmpl' => [ + '"field${chartnum}-${rownum}-${colnum}"', + '"value${chartnum}-${rownum}-${colnum}"', + '"type${chartnum}-${rownum}-${colnum}"', + 'field.name', + 'field.description', + 'type.name', + 'type.description', + '"${chartnum}-${rownum}-${newor}"', + '"${chartnum}-${newand}-0"', + 'newchart', + 'jsmagic', +], + +'search/form.html.tmpl' => [ + 'qv.value', + 'qv.name', + 'qv.description', + 'field.name', + 'field.description', + 'field.accesskey', + 'sel.name', + 'sel.accesskey', + 'button_name', # +], + +'search/knob.html.tmpl' => [ + 'button_name', # +], + +'search/search-report-graph.html.tmpl' => [ + 'button_name', # +], + +'search/search-report-table.html.tmpl' => [ + 'button_name', # +], + +'request/queue.html.tmpl' => [ + 'column_headers.$group_field', + 'column_headers.$column', + 'request.status', + 'request.bug_id', + 'request.attach_id', +], + +'reports/components.html.tmpl' => [ + 'numcols', + 'numcols - 1', + 'comp.description', + 'comp.initialowner', # email address + 'comp.initialqacontact', # email address +], + +'reports/duplicates-simple.html.tmpl' => [ + 'title', # +], + +'reports/duplicates-table.html.tmpl' => [ + '"&maxrows=$maxrows" IF maxrows', + '"&changedsince=$changedsince" IF changedsince', + '"&product=$product" IF product', # + '"&format=$format" IF format', # + '"&bug_id=$bug_ids_string&sortvisible=1" IF sortvisible', + 'column.name', + 'column.description', + 'vis_bug_ids.push(bug.id)', + 'bug.id', + 'bug.count', + 'bug.delta', + 'bug.component', # + 'bug.bug_severity', # + 'bug.op_sys', # + 'bug.target_milestone', # +], + +'reports/duplicates.html.tmpl' => [ + 'bug_ids_string', + 'maxrows', + 'changedsince', + 'reverse', +], + +'reports/keywords.html.tmpl' => [ + 'keyword.description', + 'keyword.bugcount', +], + +'reports/report-table.csv.tmpl' => [ + '"$tbl_field_disp: $tbl\n" IF tbl_field', # + 'row_field_disp IF row_field', # + 'col_field_disp', # + 'num_bugs', + 'data.$tbl.$col.$row', + '', # This is not a bug in the filter exceptions - this template has an + # empty directive which is necessary for it to work properly. +], + +'reports/report-table.html.tmpl' => [ + 'buglistbase', + '"&$tbl_vals" IF tbl_vals', + '"&$col_vals" IF col_vals', + '"&$row_vals" IF row_vals', + 'tbl_disp', # + 'classes.$row_idx.$col_idx', + 'urlbase', + 'data.$tbl.$col.$row', + 'row_total', + 'col_totals.$col', + 'grand_total', +], + +'reports/report.html.tmpl' => [ + 'tbl_field_disp IF tbl_field', # + 'row_field_disp IF row_field', # + 'col_field_disp', # + 'imagebase', + 'width', + 'height', + 'imageurl', + 'formaturl', + 'other_format.name', + 'other_format.description', # + 'sizeurl', + 'height + 100', + 'height - 100', + 'width + 100', + 'width - 100', + 'switchbase', + 'format', + 'cumulate', +], + +'reports/duplicates.rdf.tmpl' => [ + 'template_version', + 'bug.id', + 'bug.count', + 'bug.delta', +], + +'list/change-columns.html.tmpl' => [ + 'column', + 'field_descs.${column} || column', # +], + +'list/edit-multiple.html.tmpl' => [ + 'group.id', + 'group.description', + 'group.description FILTER strike', + 'knum', + 'menuname', +], + +'list/list-simple.html.tmpl' => [ + 'title', +], + +'list/list.html.tmpl' => [ + 'buglist', + 'bugowners', # email address +], + +'list/list.rdf.tmpl' => [ + 'template_version', + 'bug.bug_id', + 'column', +], + +'list/table.html.tmpl' => [ + 'id', + 'splitheader ? 2 : 1', + 'abbrev.$id.title || field_descs.$id || column.title', # + 'tableheader', + 'bug.bug_severity', # + 'bug.priority', # + 'bug.bug_id', +], + +'list/list.csv.tmpl' => [ + 'bug.bug_id', +], + +'list/list.js.tmpl' => [ + 'bug.bug_id', +], + +'global/help.html.tmpl' => [ + 'h.id', + 'h.html', +], + +'global/banner.html.tmpl' => [ + 'VERSION', +], + +'global/choose-product.html.tmpl' => [ + 'target', + 'proddesc.$p', +], + +'global/code-error.html.tmpl' => [ + 'parameters', + 'bug.bug_id', + 'field', + 'argument', # + 'function', # + 'bug_id', # Need to remove unused error no_bug_data + 'variables.id', + 'template_error_msg', # Should move filtering from CGI.pl to template + 'error', + 'error_message', +], + +'global/header.html.tmpl' => [ + 'javascript', + 'style', + 'style_url', + 'bgcolor', + 'onload', + 'h1', + 'h2', + 'h3', + 'message', +], +'global/hidden-fields.html.tmpl' => [ + 'mvalue | html | html_linebreak', # Need to eliminate | usage + 'field.value | html | html_linebreak', +], + +'global/messages.html.tmpl' => [ + 'parameters', + '# ---', # Work out what this is + 'namedcmd', # + 'old_email', # email address + 'new_email', # email address + 'message_tag', +], + +'global/select-menu.html.tmpl' => [ + 'options', + 'onchange', # Again, need to be certain where we are filtering + 'size', +], + +'global/useful-links.html.tmpl' => [ + 'email', + 'user.login', # Email address +], + +# Need to change this and code-error to use a no-op filter, for safety +'global/user-error.html.tmpl' => [ + 'disabled_reason', + 'bug_link', + 'action', # + 'bug_id', + 'both', + 'filesize', + 'attach_id', + 'field', + 'field_descs.$field', + 'today', + 'product', # + 'max', + 'votes', + 'error_message', +], + +'global/confirm-user-match.html.tmpl' => [ + '# use the global field descs', # Need to fix commenting style here + 'script', + '# this is messy to allow later expansion', + '# ELSIF for things that don\'t belong in the field_descs hash here', + 'fields.${field_name}.flag_type.name', +], + +'global/site-navigation.html.tmpl' => [ + 'bug_list.first', + 'bug_list.$prev_bug', + 'bug_list.$next_bug', + 'bug_list.last', + 'bug.bug_id', + 'bug.votes', + 'PerformSubsts(Param(\'mybugstemplate\'), substs)', +], + +'bug/comments.html.tmpl' => [ + 'comment.isprivate', + 'comment.when', +], + +'bug/dependency-graph.html.tmpl' => [ + 'image_map', # We need to continue to make sure this is safe in the CGI + 'image_url', + 'map_url', + 'bug_id', +], + +'bug/dependency-tree.html.tmpl' => [ + 'hide_resolved ? "Open b" : "B"', + 'bugid', + 'maxdepth', + 'dependson_ids.join(",")', + 'blocked_ids.join(",")', + 'dep_id', + 'hide_resolved ? 0 : 1', + 'hide_resolved ? "Show" : "Hide"', + 'realdepth < 2 || maxdepth == 1 ? "disabled" : ""', + 'hide_resolved', + 'realdepth < 2 ? "disabled" : ""', + 'maxdepth + 1', + 'maxdepth == 0 || maxdepth == realdepth ? "disabled" : ""', + 'realdepth < 2 || ( maxdepth && maxdepth < 2 ) ? "disabled" : ""', + 'maxdepth > 0 && maxdepth <= realdepth ? maxdepth : ""', + 'maxdepth == 1 ? 1 + : ( maxdepth ? maxdepth - 1 : realdepth - 1 )', + 'realdepth < 2 || ! maxdepth || maxdepth >= realdepth ? + "disabled" : ""', +], + +'bug/edit.html.tmpl' => [ + 'bug.remaining_time', + 'bug.delta_ts', + 'bug.bug_id', + 'bug.votes', + 'group.bit', + 'group.description', + 'knum', + 'dep.title', + 'dep.fieldname', + 'accesskey', + 'bug.${dep.fieldname}.join(\', \')', + 'selname', + 'depbug FILTER bug_link(depbug)', + '"bug ${bug.dup_id}" FILTER bug_link(bug.dup_id)', +], + +'bug/navigate.html.tmpl' => [ + 'this_bug_idx + 1', + 'bug_list.first', + 'bug_list.last', + 'bug_list.$prev_bug', + 'bug_list.$next_bug', +], + +'bug/show-multiple.html.tmpl' => [ + 'bug.bug_id', + 'bug.component', # + 'attr.description', # +], + +'bug/show.xml.tmpl' => [ + 'VERSION', + 'a.attachid', + 'field', +], + +'bug/time.html.tmpl' => [ + 'time_unit FILTER format(\'%.1f\')', + 'time_unit FILTER format(\'%.2f\')', + '(act / (act + rem)) * 100 + FILTER format("%d")', +], + +'bug/votes/list-for-bug.html.tmpl' => [ + 'voter.count', + 'total', +], + +'bug/votes/list-for-user.html.tmpl' => [ + 'product.maxperbug', + 'bug.id', + 'bug.count', + 'product.total', + 'product.maxvotes', +], +# h2 = voting_user.name # Email + +'bug/process/confirm-duplicate.html.tmpl' => [ + 'original_bug_id', + 'duplicate_bug_id', +], + +'bug/process/midair.html.tmpl' => [ + 'bug_id', +], + +'bug/process/next.html.tmpl' => [ + 'bug.bug_id', +], + +'bug/process/results.html.tmpl' => [ + 'title.$type', + 'id', +], + +'bug/process/verify-new-product.html.tmpl' => [ + 'form.product', # +], + +'bug/process/bugmail.html.tmpl' => [ + 'description', + 'name', # Email +], + +'bug/create/comment.txt.tmpl' => [ + 'form.comment', +], + +'bug/create/create.html.tmpl' => [ + 'default.bug_status', # + 'g.bit', + 'g.description', + 'sel.name', + 'sel.description', +], + +'bug/create/create-guided.html.tmpl' => [ + 'matches.0', + 'tablecolour', + 'product', # + 'buildid', + 'sel', +], + +'bug/activity/show.html.tmpl' => [ + 'bug_id', +], + +'bug/activity/table.html.tmpl' => [ + 'operation.who', # Email + 'change.attachid', + 'change.field', +], + +'attachment/create.html.tmpl' => [ + 'bugid', + 'attachment.id', +], + +'attachment/created.html.tmpl' => [ + 'attachid', + 'bugid', + 'contenttype', +], + +'attachment/edit.html.tmpl' => [ + 'attachid', + 'bugid', + 'a', +], + +'attachment/list.html.tmpl' => [ + 'attachment.attachid', + 'FOR flag = attachment.flags', # Bug? No FOR directive + 'flag.type.name', + 'flag.status', + 'flag.requestee.nick', # Email + 'show_attachment_flags ? 4 : 3', + 'bugid', +], + +'attachment/show-multiple.html.tmpl' => [ + 'a.attachid', +], + +'attachment/updated.html.tmpl' => [ + 'attachid', + 'bugid', +], + +'admin/products/groupcontrol/confirm-edit.html.tmpl' => [ + 'group.count', +], + +'admin/products/groupcontrol/edit.html.tmpl' => [ + 'filt_product', + 'group.bugcount', + 'group.id', + 'const.CONTROLMAPNA', + 'const.CONTROLMAPSHOWN', + 'const.CONTROLMAPDEFAULT', + 'const.CONTROLMAPMANDATORY', +], + +'admin/flag-type/confirm-delete.html.tmpl' => [ + 'flag_count', + 'name', # + 'flag_type.id', +], + +'admin/flag-type/edit.html.tmpl' => [ + 'action', + 'type.id', + 'type.target_type', + 'category', # + 'item', # + 'type.sortkey || 1', + '(last_action == "enter" || last_action == "copy") ? "Create" : "Save Changes"', +], + +'admin/flag-type/list.html.tmpl' => [ + 'type.is_active ? "active" : "inactive"', + 'type.id', + 'type.flag_count', +], + +'account/login.html.tmpl' => [ + 'target', +], + +'account/prefs/account.html.tmpl' => [ + 'login_change_date', # +], + +'account/prefs/email.html.tmpl' => [ + 'watchedusers', # Email + 'useqacontact ? \'5\' : \'4\'', + 'role', + 'reason.name', + 'reason.description', +], + +'account/prefs/permissions.html.tmpl' => [ + 'bit_description.name', + 'bit_description.desc', +], + +'account/prefs/prefs.html.tmpl' => [ + 'tab.name', + 'tab.description', + 'current_tab.name', + 'current_tab.description', + 'current_tab.description FILTER lower', +], + +); + +# Should filter reports/report.html.tmpl:130 $format diff --git a/template/en/default/global/choose-product.html.tmpl b/template/en/default/global/choose-product.html.tmpl index de0ca0be7..e79f7820d 100644 --- a/template/en/default/global/choose-product.html.tmpl +++ b/template/en/default/global/choose-product.html.tmpl @@ -41,7 +41,7 @@ <tr> <th align="right" valign="top"> <a href="[% target %]?product=[% p FILTER url_quote %] - [%- "&format=$format" IF format %]"> + [% IF format %]&format=[% format FILTER url_quote %][% END %]"> [% p FILTER html %]</a>: </th> diff --git a/template/en/default/global/code-error.html.tmpl b/template/en/default/global/code-error.html.tmpl index b35bbb064..92836f4db 100644 --- a/template/en/default/global/code-error.html.tmpl +++ b/template/en/default/global/code-error.html.tmpl @@ -86,7 +86,7 @@ [% ELSIF error == "field_type_mismatch" %] Cannot seem to handle <code>[% field %]</code> - and <code>[% type %]</code> together. + and <code>[% type FILTER html %]</code> together. [% ELSIF error == "gd_not_installed" %] Charts will not work without the GD Perl module being installed. diff --git a/template/en/default/global/hidden-fields.html.tmpl b/template/en/default/global/hidden-fields.html.tmpl index f968fab20..a824c3489 100644 --- a/template/en/default/global/hidden-fields.html.tmpl +++ b/template/en/default/global/hidden-fields.html.tmpl @@ -32,11 +32,11 @@ [% NEXT IF exclude && field.key.search(exclude) %] [% IF mform.${field.key}.size > 1 %] [% FOREACH mvalue = mform.${field.key} %] - <input type="hidden" name="[% field.key %]" + <input type="hidden" name="[% field.key FILTER html %]" value="[% mvalue | html | html_linebreak %]"> [% END %] [% ELSE %] - <input type="hidden" name="[% field.key %]" + <input type="hidden" name="[% field.key FILTER html %]" value="[% field.value | html | html_linebreak %]"> [% END %] [% END %] diff --git a/template/en/default/global/message.html.tmpl b/template/en/default/global/message.html.tmpl index f6cb321c6..58cd56908 100644 --- a/template/en/default/global/message.html.tmpl +++ b/template/en/default/global/message.html.tmpl @@ -34,7 +34,7 @@ [%# Display a URL if the calling script or message block has included one. %] [% IF url && link %] <p> - <a href="[% url %]">[% link %]</a> + <a href="[% url FILTER html %]">[% link FILTER html %]</a> </p> [% END %] diff --git a/template/en/default/global/user-error.html.tmpl b/template/en/default/global/user-error.html.tmpl index fe1d9e223..934c0511f 100644 --- a/template/en/default/global/user-error.html.tmpl +++ b/template/en/default/global/user-error.html.tmpl @@ -235,7 +235,7 @@ [% ELSIF error == "illegal_date" %] [% title = "Your Query Makes No Sense" %] - '<tt>[% date %]</tt>' is not a legal date. + '<tt>[% date FILTER html %]</tt>' is not a legal date. [% ELSIF error == "illegal_email_address" %] [% title = "Invalid Email Address" %] @@ -290,6 +290,11 @@ in your browser. To help us fix this limitation, add your comments to <a href="http://bugzilla.mozilla.org/show_bug.cgi?id=70907">bug 70907</a>. + [% ELSIF error == "invalid_changedsince" %] + [% title = "Invalid 'Changed Since'" %] + The 'changed since' value, '[% changedsince FILTER html %]', must be an + integer >= 0. + [% ELSIF error == "invalid_content_type" %] [% title = "Invalid Content-Type" %] The content type <em>[% contenttype FILTER html %]</em> is invalid. @@ -355,7 +360,7 @@ [% ELSIF error == "missing_email_type" %] [% title = "Your Query Makes No Sense" %] You must specify one or more fields in which to search for - <tt>[% email %]</tt>. + <tt>[% email FILTER html %]</tt>. [% ELSIF error == "missing_query" %] [% title = "Missing Query" %] diff --git a/template/en/default/list/change-columns.html.tmpl b/template/en/default/list/change-columns.html.tmpl index 097a886bb..7730bf78c 100644 --- a/template/en/default/list/change-columns.html.tmpl +++ b/template/en/default/list/change-columns.html.tmpl @@ -36,7 +36,7 @@ [% field_descs.qa_contact_realname = "QA Contact Realname" %] <form action="colchange.cgi"> - <input type="hidden" name="rememberedquery" value="[% buffer %]"> + <input type="hidden" name="rememberedquery" value="[% buffer FILTER html %]"> [% FOREACH column = masterlist %] <input type="checkbox" id="[% column %]" name="column_[% column %]" [% "checked='checked'" IF lsearch(collist, column) != -1 %]> @@ -65,7 +65,7 @@ </form> <form action="colchange.cgi"> - <input type="hidden" name="rememberedquery" value="[% buffer %]"> + <input type="hidden" name="rememberedquery" value="[% buffer FILTER html %]"> <input type="hidden" name="resetit" value="1"> <input type="submit" value="Reset to Bugzilla default"> </form> diff --git a/template/en/default/list/list.html.tmpl b/template/en/default/list/list.html.tmpl index 9b9f099d3..91a5584cf 100644 --- a/template/en/default/list/list.html.tmpl +++ b/template/en/default/list/list.html.tmpl @@ -95,7 +95,7 @@ <p> <a href="query.cgi">Query Page</a> <a href="enter_bug.cgi">Enter New Bug</a> - <a href="query.cgi?[% urlquerypart %]">Edit this query</a> + <a href="query.cgi?[% urlquerypart FILTER html %]">Edit this query</a> </p> [% ELSIF bugs.size == 1 %] @@ -133,11 +133,13 @@ <input type="hidden" name="buglist" value="[% buglist %]"> <input type="submit" value="Long Format"> - <a href="buglist.cgi?[% urlquerypart %]&ctype=csv">CSV</a> - <a href="colchange.cgi?[% urlquerypart %]">Change Columns</a> + <a href="buglist.cgi? + [% urlquerypart FILTER html %]&ctype=csv">CSV</a> + <a href="colchange.cgi? + [% urlquerypart FILTER html %]">Change Columns</a> [% IF bugs.size > 1 && caneditbugs && !dotweak %] - <a href="buglist.cgi?[% urlquerypart %] + <a href="buglist.cgi?[% urlquerypart FILTER html %] [%- "&order=$qorder" FILTER html IF order %]&tweak=1">Change Several Bugs at Once</a> @@ -147,7 +149,8 @@ <a href="mailto:[% bugowners %]">Send Mail to Bug Owners</a> [% END %] - <a href="query.cgi?[% urlquerypart %]">Edit this Query</a> + <a href="query.cgi? + [% urlquerypart FILTER html %]">Edit this Query</a> </form> diff --git a/template/en/default/list/table.html.tmpl b/template/en/default/list/table.html.tmpl index 8a5d3ac57..53eb52b2d 100644 --- a/template/en/default/list/table.html.tmpl +++ b/template/en/default/list/table.html.tmpl @@ -82,7 +82,8 @@ <tr align="left"> <th colspan="[% splitheader ? 2 : 1 %]"> - <a href="buglist.cgi?[% urlquerypart %]&order=bugs.bug_id">ID</a> + <a href="buglist.cgi? + [% urlquerypart FILTER html %]&order=bugs.bug_id">ID</a> </th> [% IF splitheader %] @@ -115,7 +116,7 @@ [% BLOCK columnheader %] <th colspan="[% splitheader ? 2 : 1 %]"> - <a href="buglist.cgi?[% urlquerypart %]&order= + <a href="buglist.cgi?[% urlquerypart FILTER html %]&order= [% column.name FILTER url_quote FILTER html %] [% ",$qorder" FILTER html IF order %]"> [%- abbrev.$id.title || field_descs.$id || column.title -%]</a> diff --git a/template/en/default/reports/duplicates.html.tmpl b/template/en/default/reports/duplicates.html.tmpl index ce4d07001..a522c4db7 100644 --- a/template/en/default/reports/duplicates.html.tmpl +++ b/template/en/default/reports/duplicates.html.tmpl @@ -58,7 +58,7 @@ <h3><a name="params">Change Parameters</a></h3> <form method="get" action="duplicates.cgi"> - <input type="hidden" name="sortby" value="[% sortby %]"> + <input type="hidden" name="sortby" value="[% sortby FILTER html %]"> <input type="hidden" name="reverse" value="[% reverse %]"> <input type="hidden" name="bug_id" value="[% bug_ids_string %]"> <table> diff --git a/template/en/default/search/form.html.tmpl b/template/en/default/search/form.html.tmpl index 0b80bdb26..efc5dd0b2 100644 --- a/template/en/default/search/form.html.tmpl +++ b/template/en/default/search/form.html.tmpl @@ -330,7 +330,7 @@ function selectProduct(f) { [% PROCESS "global/field-descs.none.tmpl" %] [%# If we resubmit to ourselves, we need to know if we are using a format. %] -<input type="hidden" name="query_format" value="[% format %]"> +<input type="hidden" name="query_format" value="[% format FILTER html %]"> [%# *** Summary *** %] |