(CVE-2013-0786) [SECURITY] build_subselect() leaks the existence of products and...
[WebKit-https.git] / Websites / bugs.webkit.org / Bugzilla / Keyword.pm
1 # -*- Mode: perl; indent-tabs-mode: nil -*-
2 #
3 # The contents of this file are subject to the Mozilla Public
4 # License Version 1.1 (the "License"); you may not use this file
5 # except in compliance with the License. You may obtain a copy of
6 # the License at http://www.mozilla.org/MPL/
7 #
8 # Software distributed under the License is distributed on an "AS
9 # IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
10 # implied. See the License for the specific language governing
11 # rights and limitations under the License.
12 #
13 # The Original Code is the Bugzilla Bug Tracking System.
14 #
15 # Contributor(s): Max Kanat-Alexander <mkanat@bugzilla.org>
16
17 use strict;
18
19 package Bugzilla::Keyword;
20
21 use base qw(Bugzilla::Object);
22
23 use Bugzilla::Error;
24 use Bugzilla::Util;
25
26 ###############################
27 ####    Initialization     ####
28 ###############################
29
30 use constant DB_COLUMNS => qw(
31    keyworddefs.id
32    keyworddefs.name
33    keyworddefs.description
34 );
35
36 use constant DB_TABLE => 'keyworddefs';
37
38 use constant REQUIRED_CREATE_FIELDS => qw(name description);
39
40 use constant VALIDATORS => {
41     name        => \&_check_name,
42     description => \&_check_description,
43 };
44
45 use constant UPDATE_COLUMNS => qw(
46     name
47     description
48 );
49
50 ###############################
51 ####      Accessors      ######
52 ###############################
53
54 sub description       { return $_[0]->{'description'}; }
55
56 sub bug_count {
57     my ($self) = @_;
58     return $self->{'bug_count'} if defined $self->{'bug_count'};
59     ($self->{'bug_count'}) =
60       Bugzilla->dbh->selectrow_array(
61           'SELECT COUNT(*) FROM keywords WHERE keywordid = ?', 
62           undef, $self->id);
63     return $self->{'bug_count'};
64 }
65
66 ###############################
67 ####       Mutators       #####
68 ###############################
69
70 sub set_name        { $_[0]->set('name', $_[1]); }
71 sub set_description { $_[0]->set('description', $_[1]); }
72
73 ###############################
74 ####      Subroutines    ######
75 ###############################
76
77 sub keyword_count {
78     my ($count) = 
79         Bugzilla->dbh->selectrow_array('SELECT COUNT(*) FROM keyworddefs');
80     return $count;
81 }
82
83 sub get_all_with_bug_count {
84     my $class = shift;
85     my $dbh = Bugzilla->dbh;
86     my $keywords =
87       $dbh->selectall_arrayref('SELECT ' . join(', ', DB_COLUMNS) . ',
88                                        COUNT(keywords.bug_id) AS bug_count
89                                   FROM keyworddefs
90                              LEFT JOIN keywords
91                                     ON keyworddefs.id = keywords.keywordid ' .
92                                   $dbh->sql_group_by('keyworddefs.id',
93                                                      'keyworddefs.name,
94                                                       keyworddefs.description') . '
95                                  ORDER BY keyworddefs.name', {'Slice' => {}});
96     if (!$keywords) {
97         return [];
98     }
99     
100     foreach my $keyword (@$keywords) {
101         bless($keyword, $class);
102     }
103     return $keywords;
104 }
105
106 ###############################
107 ###       Validators        ###
108 ###############################
109
110 sub _check_name {
111     my ($self, $name) = @_;
112
113     $name = trim($name);
114     $name eq "" && ThrowUserError("keyword_blank_name");
115     if ($name =~ /[\s,]/) {
116         ThrowUserError("keyword_invalid_name");
117     }
118
119     # We only want to validate the non-existence of the name if
120     # we're creating a new Keyword or actually renaming the keyword.
121     if (!ref($self) || $self->name ne $name) {
122         my $keyword = new Bugzilla::Keyword({ name => $name });
123         ThrowUserError("keyword_already_exists", { name => $name }) if $keyword;
124     }
125
126     return $name;
127 }
128
129 sub _check_description {
130     my ($self, $desc) = @_;
131     $desc = trim($desc);
132     $desc eq '' && ThrowUserError("keyword_blank_description");
133     return $desc;
134 }
135
136 1;
137
138 __END__
139
140 =head1 NAME
141
142 Bugzilla::Keyword - A Keyword that can be added to a bug.
143
144 =head1 SYNOPSIS
145
146  use Bugzilla::Keyword;
147
148  my $count = Bugzilla::Keyword::keyword_count;
149
150  my $description = $keyword->description;
151
152  my $keywords = Bugzilla::Keyword->get_all_with_bug_count();
153
154 =head1 DESCRIPTION
155
156 Bugzilla::Keyword represents a keyword that can be added to a bug.
157
158 This implements all standard C<Bugzilla::Object> methods. See 
159 L<Bugzilla::Object> for more details.
160
161 =head1 SUBROUTINES
162
163 This is only a list of subroutines specific to C<Bugzilla::Keyword>.
164 See L<Bugzilla::Object> for more subroutines that this object 
165 implements.
166
167 =over
168
169 =item C<keyword_count()> 
170
171  Description: A utility function to get the total number
172               of keywords defined. Mostly used to see
173               if there are any keywords defined at all.
174  Params:      none
175  Returns:     An integer, the count of keywords.
176
177 =item C<get_all_with_bug_count()> 
178
179  Description: Returns all defined keywords. This is an efficient way
180               to get the associated bug counts, as only one SQL query
181               is executed with this method, instead of one per keyword
182               when calling get_all and then bug_count.
183  Params:      none
184  Returns:     A reference to an array of Keyword objects, or an empty
185               arrayref if there are no keywords.
186
187 =back
188
189 =cut