(CVE-2013-0786) [SECURITY] build_subselect() leaks the existence of products and...
[WebKit-https.git] / Websites / bugs.webkit.org / Bugzilla / Hook.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 # The Initial Developer of the Original Code is Netscape Communications
16 # Corporation. Portions created by Netscape are
17 # Copyright (C) 1998 Netscape Communications Corporation. All
18 # Rights Reserved.
19 #
20 # Contributor(s): Zach Lipton <zach@zachlipton.com>
21 #
22
23 package Bugzilla::Hook;
24
25 use Bugzilla::Constants;
26 use Bugzilla::Util;
27 use Bugzilla::Error;
28
29 use strict;
30
31 sub process {
32     my ($name, $args) = @_;
33     
34     # get a list of all extensions
35     my @extensions = glob(bz_locations()->{'extensionsdir'} . "/*");
36     
37     # check each extension to see if it uses the hook
38     # if so, invoke the extension source file:
39     foreach my $extension (@extensions) {
40         # all of these variables come directly from code or directory names. 
41         # If there's malicious data here, we have much bigger issues to 
42         # worry about, so we can safely detaint them:
43         trick_taint($extension);
44         # Skip CVS directories and any hidden files/dirs.
45         next if $extension =~ m{/CVS$} || $extension =~ m{/\.[^/]+$};
46         next if -e "$extension/disabled";
47         if (-e $extension.'/code/'.$name.'.pl') {
48             Bugzilla->hook_args($args);
49             # Allow extensions to load their own libraries.
50             local @INC = ("$extension/lib", @INC);
51             do($extension.'/code/'.$name.'.pl');
52             ThrowCodeError('extension_invalid', 
53                 { errstr => $@, name => $name, extension => $extension }) if $@;
54             # Flush stored data.
55             Bugzilla->hook_args({});
56         }
57     }
58 }
59
60 sub enabled_plugins {
61     my $extdir = bz_locations()->{'extensionsdir'};
62     my @extensions = glob("$extdir/*");
63     my %enabled;
64     foreach my $extension (@extensions) {
65         trick_taint($extension);
66         my $extname = $extension;
67         $extname =~ s{^\Q$extdir\E/}{};
68         next if $extname eq 'CVS' || $extname =~ /^\./;
69         next if -e "$extension/disabled";
70         # Allow extensions to load their own libraries.
71         local @INC = ("$extension/lib", @INC);
72         $enabled{$extname} = do("$extension/info.pl");
73         ThrowCodeError('extension_invalid',
74                 { errstr => $@, name => 'version',
75                   extension => $extension }) if $@;
76
77     }
78
79     return \%enabled;
80 }
81
82 1;
83
84 __END__
85
86 =head1 NAME
87
88 Bugzilla::Hook - Extendable extension hooks for Bugzilla code
89
90 =head1 SYNOPSIS
91
92  use Bugzilla::Hook;
93
94  Bugzilla::Hook::process("hookname", { arg => $value, arg2 => $value2 });
95
96 =head1 DESCRIPTION
97
98 Bugzilla allows extension modules to drop in and add routines at 
99 arbitrary points in Bugzilla code. These points are referred to as
100 hooks. When a piece of standard Bugzilla code wants to allow an extension
101 to perform additional functions, it uses Bugzilla::Hook's L</process>
102 subroutine to invoke any extension code if installed. 
103
104 There is a sample extension in F<extensions/example/> that demonstrates
105 most of the things described in this document, as well as many of the
106 hooks available.
107
108 =head2 How Hooks Work
109
110 When a hook named C<HOOK_NAME> is run, Bugzilla will attempt to invoke any 
111 source files named F<extensions/*/code/HOOK_NAME.pl>.
112
113 So, for example, if your extension is called "testopia", and you
114 want to have code run during the L</install-update_db> hook, you
115 would have a file called F<extensions/testopia/code/install-update_db.pl>
116 that contained perl code to run during that hook.
117
118 =head2 Arguments Passed to Hooks
119
120 Some L<hooks|/HOOKS> have params that are passed to them.
121
122 These params are accessible through L<Bugzilla/hook_args>.
123 That returns a hashref. Very frequently, if you want your
124 hook to do anything, you have to modify these variables.
125
126 =head2 Versioning Extensions
127
128 Every extension must have a file in its root called F<info.pl>.
129 This file must return a hash when called with C<do>.
130 The hash must contain a 'version' key with the current version of the
131 extension. Extension authors can also add any extra infomration to this hash if
132 required, by adding a new key beginning with x_ which will not be used the
133 core Bugzilla code. 
134
135 =head1 SUBROUTINES
136
137 =over
138
139 =item C<process>
140
141 =over
142
143 =item B<Description>
144
145 Invoke any code hooks with a matching name from any installed extensions.
146
147 See C<customization.xml> in the Bugzilla Guide for more information on
148 Bugzilla's extension mechanism.
149
150 =item B<Params>
151
152 =over
153
154 =item C<$name> - The name of the hook to invoke.
155
156 =item C<$args> - A hashref. The named args to pass to the hook. 
157 They will be accessible to the hook via L<Bugzilla/hook_args>.
158
159 =back
160
161 =item B<Returns> (nothing)
162
163 =back
164
165 =back
166
167 =head1 HOOKS
168
169 This describes what hooks exist in Bugzilla currently. They are mostly
170 in alphabetical order, but some related hooks are near each other instead
171 of being alphabetical.
172
173 =head2 bug-end_of_update
174
175 This happens at the end of L<Bugzilla::Bug/update>, after all other changes are
176 made to the database. This generally occurs inside a database transaction.
177
178 Params:
179
180 =over
181
182 =item C<bug> - The changed bug object, with all fields set to their updated
183 values.
184
185 =item C<timestamp> - The timestamp used for all updates in this transaction.
186
187 =item C<changes> - The hash of changed fields. 
188 C<$changes-E<gt>{field} = [old, new]>
189
190 =back
191
192 =head2 buglist-columns
193
194 This happens in buglist.cgi after the standard columns have been defined and
195 right before the display column determination.  It gives you the opportunity
196 to add additional display columns.
197
198 Params:
199
200 =over
201
202 =item C<columns> - A hashref, where the keys are unique string identifiers
203 for the column being defined and the values are hashrefs with the
204 following fields:
205
206 =over
207
208 =item C<name> - The name of the column in the database.
209
210 =item C<title> - The title of the column as displayed to users.
211
212 =back
213
214 The definition is structured as:
215
216  $columns->{$id} = { name => $name, title => $title };
217
218 =back
219
220 =head2 colchange-columns
221
222 This happens in F<colchange.cgi> right after the list of possible display
223 columns have been defined and gives you the opportunity to add additional
224 display columns to the list of selectable columns.
225
226 Params:
227
228 =over
229
230 =item C<columns> - An arrayref containing an array of column IDs.  Any IDs
231 added by this hook must have been defined in the the buglist-columns hook.
232 See L</buglist-columns>.
233
234 =back
235
236 =head2 enter_bug-entrydefaultvars
237
238 This happens right before the template is loaded on enter_bug.cgi.
239
240 Params:
241
242 =over
243
244 =item C<vars> - A hashref. The variables that will be passed into the template.
245
246 =back
247
248 =head2 flag-end_of_update
249
250 This happens at the end of L<Bugzilla::Flag/process>, after all other changes
251 are made to the database and after emails are sent. It gives you a before/after
252 snapshot of flags so you can react to specific flag changes.
253 This generally occurs inside a database transaction.
254
255 Note that the interface to this hook is B<UNSTABLE> and it may change in the
256 future.
257
258 Params:
259
260 =over
261
262 =item C<bug> - The changed bug object.
263
264 =item C<timestamp> - The timestamp used for all updates in this transaction.
265
266 =item C<old_flags> - The snapshot of flag summaries from before the change.
267
268 =item C<new_flags> - The snapshot of flag summaries after the change. Call
269 C<my ($removed, $added) = diff_arrays(old_flags, new_flags)> to get the list of
270 changed flags, and search for a specific condition like C<added eq 'review-'>.
271
272 =back
273
274 =head2 install-before_final_checks
275
276 Allows execution of custom code before the final checks are done in 
277 checksetup.pl.
278
279 Params:
280
281 =over
282
283 =item C<silent>
284
285 A flag that indicates whether or not checksetup is running in silent mode.
286
287 =back
288
289 =head2 install-requirements
290
291 Because of the way Bugzilla installation works, there can't be a normal
292 hook during the time that F<checksetup.pl> checks what modules are
293 installed. (C<Bugzilla::Hook> needs to have those modules installed--it's
294 a chicken-and-egg problem.)
295
296 So instead of the way hooks normally work, this hook just looks for two 
297 subroutines (or constants, since all constants are just subroutines) in 
298 your file, called C<OPTIONAL_MODULES> and C<REQUIRED_MODULES>,
299 which should return arrayrefs in the same format as C<OPTIONAL_MODULES> and
300 C<REQUIRED_MODULES> in L<Bugzilla::Install::Requirements>.
301
302 These subroutines will be passed an arrayref that contains the current
303 Bugzilla requirements of the same type, in case you want to modify
304 Bugzilla's requirements somehow. (Probably the most common would be to
305 alter a version number or the "feature" element of C<OPTIONAL_MODULES>.)
306
307 F<checksetup.pl> will add these requirements to its own.
308
309 Please remember--if you put something in C<REQUIRED_MODULES>, then
310 F<checksetup.pl> B<cannot complete> unless the user has that module
311 installed! So use C<OPTIONAL_MODULES> whenever you can.
312
313 =head2 install-update_db
314
315 This happens at the very end of all the tables being updated
316 during an installation or upgrade. If you need to modify your custom
317 schema, do it here. No params are passed.
318
319 =head2 db_schema-abstract_schema
320
321 This allows you to add tables to Bugzilla. Note that we recommend that you 
322 prefix the names of your tables with some word, so that they don't conflict 
323 with any future Bugzilla tables.
324
325 If you wish to add new I<columns> to existing Bugzilla tables, do that
326 in L</install-update_db>.
327
328 Params:
329
330 =over
331
332 =item C<schema> - A hashref, in the format of 
333 L<Bugzilla::DB::Schema/ABSTRACT_SCHEMA>. Add new hash keys to make new table
334 definitions. F<checksetup.pl> will automatically add these tables to the
335 database when run.
336
337 =back
338
339 =head2 product-confirm_delete
340
341 Called before displaying the confirmation message when deleting a product.
342
343 Params:
344
345 =over
346
347 =item C<vars> - The template vars hashref.
348
349 =back
350
351 =head2 webservice
352
353 This hook allows you to add your own modules to the WebService. (See
354 L<Bugzilla::WebService>.)
355
356 Params:
357
358 =over
359
360 =item C<dispatch>
361
362 A hashref that you can specify the names of your modules and what Perl
363 module handles the functions for that module. (This is actually sent to 
364 L<SOAP::Lite/dispatch_with>. You can see how that's used in F<xmlrpc.cgi>.)
365
366 The Perl module name must start with C<extensions::yourextension::lib::>
367 (replace C<yourextension> with the name of your extension). The C<package>
368 declaration inside that module must also start with 
369 C<extensions::yourextension::lib::> in that module's code.
370
371 Example:
372
373   $dispatch->{Example} = "extensions::example::lib::Example";
374
375 And then you'd have a module F<extensions/example/lib/Example.pm>
376
377 It's recommended that all the keys you put in C<dispatch> start with the
378 name of your extension, so that you don't conflict with the standard Bugzilla
379 WebService functions (and so that you also don't conflict with other
380 plugins).
381
382 =back
383
384 =head2 webservice-error_codes
385
386 If your webservice extension throws custom errors, you can set numeric
387 codes for those errors here.
388
389 Extensions should use error codes above 10000, unless they are re-using
390 an already-existing error code.
391
392 Params:
393
394 =over
395
396 =item C<error_map>
397
398 A hash that maps the names of errors (like C<invalid_param>) to numbers.
399 See L<Bugzilla::WebService::Constants/WS_ERROR_CODE> for an example.
400
401 =back