[Rt-commit] r2824 - in rt/branches/CHALDEA-EXPERIMENTAL/lib: RT t/regression

autrijus at bestpractical.com autrijus at bestpractical.com
Tue May 3 07:26:00 EDT 2005


Author: autrijus
Date: Tue May  3 07:25:59 2005
New Revision: 2824

Added:
   rt/branches/CHALDEA-EXPERIMENTAL/lib/t/regression/15cf_pattern.t
Modified:
   rt/branches/CHALDEA-EXPERIMENTAL/lib/RT/CustomField_Overlay.pm
   rt/branches/CHALDEA-EXPERIMENTAL/lib/RT/Record.pm
Log:
* `CF.Pattern` now works at API level:
** Reject invalid regex as patterns.
** Validate new CF values against the current pattern.

Modified: rt/branches/CHALDEA-EXPERIMENTAL/lib/RT/CustomField_Overlay.pm
==============================================================================
--- rt/branches/CHALDEA-EXPERIMENTAL/lib/RT/CustomField_Overlay.pm	(original)
+++ rt/branches/CHALDEA-EXPERIMENTAL/lib/RT/CustomField_Overlay.pm	Tue May  3 07:25:59 2005
@@ -166,6 +166,12 @@
         }
 	$args{'LookupType'} = 'RT::Queue-RT::Ticket';
     }
+
+    my ($ok, $msg) = $self->_IsValidRegex($args{'Pattern'});
+    if (!$ok) {
+        return (0, $self->loc("Invalid pattern: [_1]", $msg));
+    }
+
     my $rv = $self->SUPER::Create(
                          Name => $args{'Name'},
                          Type => $args{'Type'},
@@ -628,6 +634,50 @@
     $self->SUPER::SetType($type);
 }
 
+=head2 SetPattern STRING
+
+Takes a single string representing a regular expression.  Performs basic
+validation on that regex, and sets the C<Pattern> field for the CF if it
+is valid.
+
+=cut
+
+sub SetPattern {
+    my $self = shift;
+    my $regex = shift;
+
+    my ($ok, $msg) = $self->_IsValidRegex($regex);
+    if ($ok) {
+        return $self->SUPER::SetPattern($regex);
+    }
+    else {
+        return (0, $self->loc("Invalid pattern: [_1]", $msg));
+    }
+}
+
+=head2 _IsValidRegex(Str $regex) returns (Bool $success, Str $msg)
+
+Tests if the string contains an invalid regex.
+
+=cut
+
+sub _IsValidRegex {
+    my $self  = shift;
+    my $regex = shift or return (1, 'valid');
+
+    local $^W; local $@;
+    $SIG{__DIE__} = sub { 1 };
+    $SIG{__WARN__} = sub { 1 };
+
+    if (eval { qr/$regex/; 1 }) {
+        return (1, 'valid');
+    }
+
+    my $err = $@;
+    $err =~ s{[,;].*}{};    # strip debug info from error
+    return (0, $err);
+}
+
 # {{{ SingleValue
 
 =head2 SingleValue
@@ -940,6 +990,10 @@
         return ( 0, $self->loc('Permission Denied') );
     }
 
+    unless ( $self->_MatchPattern($args{Content}) ) {
+        return ( 0, $self->loc('Invalid input') );
+    }
+
     $RT::Handle->BeginTransaction;
 
     my $current_values = $self->ValuesForObject($obj);
@@ -988,6 +1042,15 @@
 
 }
 
+sub _MatchPattern {
+    my $self = shift;
+    my $regex = $self->Pattern;
+
+    return 1 if !length($regex);
+    return ($_[0] =~ $regex);
+}
+
+
 # }}}
 
 # {{{ DeleteValueForObject

Modified: rt/branches/CHALDEA-EXPERIMENTAL/lib/RT/Record.pm
==============================================================================
--- rt/branches/CHALDEA-EXPERIMENTAL/lib/RT/Record.pm	(original)
+++ rt/branches/CHALDEA-EXPERIMENTAL/lib/RT/Record.pm	Tue May  3 07:25:59 2005
@@ -1646,7 +1646,7 @@
         );
 
         unless ($new_value_id) {
-            return ( 0, $self->loc( "Could not add new custom field value. [_1] ",, $value_msg));
+            return ( 0, $self->loc( "Could not add new custom field value. [_1] ", $value_msg));
         }
 
         my $new_value = RT::ObjectCustomFieldValue->new( $self->CurrentUser );
@@ -1685,7 +1685,7 @@
 
     # otherwise, just add a new value and record "new value added"
     else {
-        my ($new_value_id) = $cf->AddValueForObject(
+        my ($new_value_id, $value_msg) = $cf->AddValueForObject(
             Object       => $self,
             Content      => $args{'Value'},
             LargeContent => $args{'LargeContent'},
@@ -1693,7 +1693,7 @@
         );
 
         unless ($new_value_id) {
-            return ( 0, $self->loc("Could not add new custom field value. ") );
+            return ( 0, $self->loc( "Could not add new custom field value. [_1] ", $value_msg));
         }
         if ( $args{'RecordTransaction'} ) {
             my ( $TransactionId, $Msg, $TransactionObj ) =

Added: rt/branches/CHALDEA-EXPERIMENTAL/lib/t/regression/15cf_pattern.t
==============================================================================
--- (empty file)
+++ rt/branches/CHALDEA-EXPERIMENTAL/lib/t/regression/15cf_pattern.t	Tue May  3 07:25:59 2005
@@ -0,0 +1,48 @@
+#!/usr/bin/perl
+use warnings;
+use strict;
+use Test::More qw/no_plan/;
+
+use RT;
+RT::LoadConfig();
+RT::Init();
+
+sub fail_ok {
+    my ($cond, $msg) = @_;
+    ok(!$cond, "This should fail: $msg");
+}
+
+sub new (*) {
+    my $class = shift;
+    return $class->new($RT::SystemUser);
+}
+
+my $q = new(RT::Queue);
+ok($q->Create(Name => "CF-Pattern-".$$));
+
+my $cf = new(RT::CustomField);
+my @cf_args = (Name => $q->Name, Type => 'Freeform', Queue => $q->id);
+
+fail_ok($cf->Create(@cf_args, Pattern => ')))bad!regex((('));
+ok($cf->Create(@cf_args, Pattern => 'good regex'));
+
+my $t = new(RT::Ticket);
+my ($id,undef,$msg) = $t->Create(Queue => $q->id, Subject => 'CF Test');
+ok($id,$msg);
+
+# OK, I'm thoroughly brain washed by HOP at this point now...
+sub cnt { $t->CustomFieldValues($cf->id)->Count };
+sub add { $t->AddCustomFieldValue(Field => $cf->id, Value => $_[0]) };
+
+is(cnt(), 0, "No values yet");
+fail_ok(add('not going to match'));
+is(cnt(), 0, "No values yet");
+ok(add('here is a good regex'));
+is(cnt(), 1, "Value filled");
+
+fail_ok($cf->SetPattern('(?{ "insert evil code here" })'));
+ok($cf->SetPattern('(?!)')); # reject everything
+fail_ok(add(''));
+fail_ok(add('...'));
+
+1;


More information about the Rt-commit mailing list