summaryrefslogtreecommitdiffstats
path: root/Bugzilla
diff options
context:
space:
mode:
Diffstat (limited to 'Bugzilla')
-rwxr-xr-xBugzilla/Bug.pm25
-rw-r--r--Bugzilla/Constants.pm2
-rw-r--r--Bugzilla/Field.pm3
-rw-r--r--Bugzilla/Util.pm17
4 files changed, 46 insertions, 1 deletions
diff --git a/Bugzilla/Bug.pm b/Bugzilla/Bug.pm
index ed398f0fe..ba66e846f 100755
--- a/Bugzilla/Bug.pm
+++ b/Bugzilla/Bug.pm
@@ -145,6 +145,9 @@ sub VALIDATORS {
elsif ($field->type == FIELD_TYPE_MULTI_SELECT) {
$validator = \&_check_multi_select_field;
}
+ elsif ($field->type == FIELD_TYPE_DATETIME) {
+ $validator = \&_check_datetime_field;
+ }
else {
$validator = \&_check_freetext_field;
}
@@ -1240,6 +1243,28 @@ sub _check_work_time {
# Custom Field Validators
+sub _check_datetime_field {
+ my ($invocant, $date_time) = @_;
+
+ # Empty datetimes are empty strings or strings only containing
+ # 0's, whitespace, and punctuation.
+ if ($date_time =~ /^[\s0[:punct:]]*$/) {
+ return undef;
+ }
+
+ $date_time = trim($date_time);
+ my ($date, $time) = split(' ', $date_time);
+ if ($date && !validate_date($date)) {
+ ThrowUserError('illegal_date', { date => $date,
+ format => 'YYYY-MM-DD' });
+ }
+ if ($time && !validate_time($time)) {
+ ThrowUserError('illegal_time', { 'time' => $time,
+ format => 'HH:MM:SS' });
+ }
+ return $date_time
+}
+
sub _check_multi_select_field {
my ($invocant, $values, $field) = @_;
return [] if !$values;
diff --git a/Bugzilla/Constants.pm b/Bugzilla/Constants.pm
index 827bb2d4b..12d54abee 100644
--- a/Bugzilla/Constants.pm
+++ b/Bugzilla/Constants.pm
@@ -121,6 +121,7 @@ use File::Basename;
FIELD_TYPE_SINGLE_SELECT
FIELD_TYPE_MULTI_SELECT
FIELD_TYPE_TEXTAREA
+ FIELD_TYPE_DATETIME
USAGE_MODE_BROWSER
USAGE_MODE_CMDLINE
@@ -349,6 +350,7 @@ use constant FIELD_TYPE_FREETEXT => 1;
use constant FIELD_TYPE_SINGLE_SELECT => 2;
use constant FIELD_TYPE_MULTI_SELECT => 3;
use constant FIELD_TYPE_TEXTAREA => 4;
+use constant FIELD_TYPE_DATETIME => 5;
# The maximum number of days a token will remain valid.
use constant MAX_TOKEN_AGE => 3;
diff --git a/Bugzilla/Field.pm b/Bugzilla/Field.pm
index 34a1818de..5ad5e51d3 100644
--- a/Bugzilla/Field.pm
+++ b/Bugzilla/Field.pm
@@ -127,6 +127,7 @@ use constant SQL_DEFINITIONS => {
FIELD_TYPE_SINGLE_SELECT, { TYPE => 'varchar(64)', NOTNULL => 1,
DEFAULT => "'---'" },
FIELD_TYPE_TEXTAREA, { TYPE => 'MEDIUMTEXT' },
+ FIELD_TYPE_DATETIME, { TYPE => 'DATETIME' },
};
# Field definitions for the fields that ship with Bugzilla.
@@ -255,7 +256,7 @@ sub _check_type {
my $saved_type = $type;
# The constant here should be updated every time a new,
# higher field type is added.
- (detaint_natural($type) && $type <= FIELD_TYPE_TEXTAREA)
+ (detaint_natural($type) && $type <= FIELD_TYPE_DATETIME)
|| ThrowCodeError('invalid_customfield_type', { type => $saved_type });
return $type;
}
diff --git a/Bugzilla/Util.pm b/Bugzilla/Util.pm
index 5c68a9092..ffc2af95a 100644
--- a/Bugzilla/Util.pm
+++ b/Bugzilla/Util.pm
@@ -40,6 +40,7 @@ use base qw(Exporter);
diff_arrays diff_strings
trim wrap_comment find_wrap_point
format_time format_time_decimal validate_date
+ validate_time
file_mod_time is_7bit_clean
bz_crypt generate_random_password
validate_email_syntax clean_text
@@ -457,6 +458,22 @@ sub validate_date {
return $ret ? 1 : 0;
}
+sub validate_time {
+ my ($time) = @_;
+ my $time2;
+
+ # $ts is undefined if the parser fails.
+ my $ts = str2time($time);
+ if ($ts) {
+ $time2 = time2str("%H:%M:%S", $ts);
+
+ $time =~ s/(\d+):(\d+?):(\d+?)/$1:$2:$3/;
+ $time2 =~ s/(\d+):(\d+?):(\d+?)/$1:$2:$3/;
+ }
+ my $ret = ($ts && $time eq $time2);
+ return $ret ? 1 : 0;
+}
+
sub is_7bit_clean {
return $_[0] !~ /[^\x20-\x7E\x0A\x0D]/;
}