]> Dogcows Code - chaz/p5-CGI-Ex/commitdiff
CGI::Ex 2.21 v2.21
authorPaul Seamons <perl@seamons.com>
Thu, 18 Oct 2007 00:00:00 +0000 (00:00 +0000)
committerCharles McGarvey <chazmcgarvey@brokenzipper.com>
Fri, 9 May 2014 23:46:43 +0000 (17:46 -0600)
12 files changed:
Changes
META.yml
lib/CGI/Ex.pm
lib/CGI/Ex/App.pm
lib/CGI/Ex/Auth.pm
lib/CGI/Ex/Conf.pm
lib/CGI/Ex/Die.pm
lib/CGI/Ex/Dump.pm
lib/CGI/Ex/Fill.pm
lib/CGI/Ex/JSONDump.pm
lib/CGI/Ex/Template.pm
lib/CGI/Ex/Validate.pm

diff --git a/Changes b/Changes
index f1577ae3f41e471ccc943eba34899d0fdbd8e045..72d28751f7a77b1ec44a26b3a4b673df5aad439c 100644 (file)
--- a/Changes
+++ b/Changes
@@ -1,3 +1,10 @@
+2.21
+     2007-10-18
+        * Add logout_hook to Auth
+        * Remove key_payload
+        * Only accept payload from cram styles
+        * Added disable_simple_cram to enforce protecting server generated payloads
+
 2.20
      2007-10-08
         * Added success_hook and failure_hook to Auth (not documented)
 2.20
      2007-10-08
         * Added success_hook and failure_hook to Auth (not documented)
index 8a005adb3e04affd93442b8352e513ebdd0be023..1d67b9189c433e25a87327d87ec5df14e58b1cfd 100644 (file)
--- a/META.yml
+++ b/META.yml
@@ -1,6 +1,6 @@
 --- #YAML:1.0
 name:                CGI-Ex
 --- #YAML:1.0
 name:                CGI-Ex
-version:             2.20
+version:             2.21
 abstract:            CGI utility suite - makes powerful application writing fun and easy
 license:             ~
 generated_by:        ExtUtils::MakeMaker version 6.36
 abstract:            CGI utility suite - makes powerful application writing fun and easy
 license:             ~
 generated_by:        ExtUtils::MakeMaker version 6.36
index faa5a3614da050b1e72059cdd255b983dde40ea4..bf4bc0217b1805671b366ffbbadbfefb3b583f6a 100644 (file)
@@ -24,7 +24,7 @@ use vars qw($VERSION
 use base qw(Exporter);
 
 BEGIN {
 use base qw(Exporter);
 
 BEGIN {
-    $VERSION               = '2.20';
+    $VERSION               = '2.21';
     $PREFERRED_CGI_MODULE  ||= 'CGI';
     @EXPORT = ();
     @EXPORT_OK = qw(get_form
     $PREFERRED_CGI_MODULE  ||= 'CGI';
     @EXPORT = ();
     @EXPORT_OK = qw(get_form
index 5e78cc3e398bc92eb8130f992f14c1027fd47b60..4c93364aceb76c22d38742b43acf1dcf8504db5b 100644 (file)
@@ -13,7 +13,7 @@ BEGIN {
     eval { use Scalar::Util };
 }
 
     eval { use Scalar::Util };
 }
 
-our $VERSION = '2.20';
+our $VERSION = '2.21';
 
 sub new {
     my $class = shift || croak "Usage: ".__PACKAGE__."->new";
 
 sub new {
     my $class = shift || croak "Usage: ".__PACKAGE__."->new";
index a762ead3de1944ae0b767ad913319dc2f7b27836..2dd895debd86b62410bf600898e4792b1fa41ebd 100644 (file)
@@ -18,7 +18,7 @@ use MIME::Base64 qw(encode_base64 decode_base64);
 use Digest::MD5 qw(md5_hex);
 use CGI::Ex;
 
 use Digest::MD5 qw(md5_hex);
 use CGI::Ex;
 
-$VERSION = '2.20';
+$VERSION = '2.21';
 
 ###----------------------------------------------------------------###
 
 
 ###----------------------------------------------------------------###
 
@@ -49,6 +49,8 @@ sub get_valid_auth {
         local $self->{'no_cookie_verify'} = 1;
         $self->check_valid_auth; # verify the logout so we can capture the username if possible
 
         local $self->{'no_cookie_verify'} = 1;
         $self->check_valid_auth; # verify the logout so we can capture the username if possible
 
+        $self->logout_hook;
+
         if ($self->bounce_on_logout) {
             my $key_c = $self->key_cookie;
             $self->delete_cookie({key => $key_c}) if $self->cookies->{$key_c};
         if ($self->bounce_on_logout) {
             my $key_c = $self->key_cookie;
             $self->delete_cookie({key => $key_c}) if $self->cookies->{$key_c};
@@ -88,7 +90,6 @@ sub get_valid_auth {
                     user        => delete $hash->{$key},
                     test_pass   => delete $hash->{ $self->key_pass },
                     expires_min => delete($hash->{ $self->key_save }) ? -1 : delete($hash->{ $self->key_expires_min }) || $self->expires_min,
                     user        => delete $hash->{$key},
                     test_pass   => delete $hash->{ $self->key_pass },
                     expires_min => delete($hash->{ $self->key_save }) ? -1 : delete($hash->{ $self->key_expires_min }) || $self->expires_min,
-                    payload     => delete $hash->{ $self->key_payload } || '',
                 },
                 from => 'form',
             }) || next;
                 },
                 from => 'form',
             }) || next;
@@ -99,12 +100,13 @@ sub get_valid_auth {
         }
 
         ### generate a fresh cookie if they submitted info on plaintext types
         }
 
         ### generate a fresh cookie if they submitted info on plaintext types
-        if ($self->use_plaintext || ($data->{'type'} && $data->{'type'} eq 'crypt')) {
+        if ($is_form
+            && ($self->use_plaintext || ($data->{'type'} && $data->{'type'} eq 'crypt'))) {
             $self->set_cookie({
                 key        => $self->key_cookie,
                 val        => $self->generate_token($data),
                 no_expires => ($data->{ $self->key_save } ? 0 : 1), # make it a session cookie unless they ask for saving
             $self->set_cookie({
                 key        => $self->key_cookie,
                 val        => $self->generate_token($data),
                 no_expires => ($data->{ $self->key_save } ? 0 : 1), # make it a session cookie unless they ask for saving
-            }) if $is_form; # only set the cookie if we found info in the form - the cookie will be a session cookie after that
+            });
 
         ### always generate a cookie on types that have expiration
         } else {
 
         ### always generate a cookie on types that have expiration
         } else {
@@ -160,6 +162,14 @@ sub success_hook {
     return;
 }
 
     return;
 }
 
+sub logout_hook {
+    my $self = shift;
+    if (my $meth = $self->{'logout_hook'}) {
+        return $meth->($self);
+    }
+    return;
+}
+
 sub handle_failure {
     my $self = shift;
     my $args = shift || {};
 sub handle_failure {
     my $self = shift;
     my $args = shift || {};
@@ -287,7 +297,6 @@ sub key_expires_min  { shift->{'key_expires_min'}  ||= 'cea_expires_min' }
 sub form_name        { shift->{'form_name'}        ||= 'cea_form'     }
 sub key_verify       { shift->{'key_verify'}       ||= 'cea_verify'   }
 sub key_redirect     { shift->{'key_redirect'}     ||= 'cea_redirect' }
 sub form_name        { shift->{'form_name'}        ||= 'cea_form'     }
 sub key_verify       { shift->{'key_verify'}       ||= 'cea_verify'   }
 sub key_redirect     { shift->{'key_redirect'}     ||= 'cea_redirect' }
-sub key_payload      { shift->{'key_payload'}      ||= 'cea_payload'  }
 sub key_loggedout    { shift->{'key_loggedout'}    ||= 'loggedout'    }
 sub bounce_on_logout { shift->{'bounce_on_logout'} ||= 0              }
 sub secure_hash_keys { shift->{'secure_hash_keys'} ||= []             }
 sub key_loggedout    { shift->{'key_loggedout'}    ||= 'loggedout'    }
 sub bounce_on_logout { shift->{'bounce_on_logout'} ||= 0              }
 sub secure_hash_keys { shift->{'secure_hash_keys'} ||= []             }
@@ -299,6 +308,7 @@ sub use_plaintext    { my $s = shift; $s->use_crypt || ($s->{'use_plaintext'} ||
 sub use_base64       { my $s = shift; $s->{'use_base64'}  = 1      if ! defined $s->{'use_base64'};  $s->{'use_base64'}  }
 sub expires_min      { my $s = shift; $s->{'expires_min'} = 6 * 60 if ! defined $s->{'expires_min'}; $s->{'expires_min'} }
 sub failed_sleep     { shift->{'failed_sleep'}     ||= 0              }
 sub use_base64       { my $s = shift; $s->{'use_base64'}  = 1      if ! defined $s->{'use_base64'};  $s->{'use_base64'}  }
 sub expires_min      { my $s = shift; $s->{'expires_min'} = 6 * 60 if ! defined $s->{'expires_min'}; $s->{'expires_min'} }
 sub failed_sleep     { shift->{'failed_sleep'}     ||= 0              }
+sub disable_simple_cram { shift->{'disable_simple_cram'} }
 
 sub logout_redirect {
     my ($self, $user) = @_;
 
 sub logout_redirect {
     my ($self, $user) = @_;
@@ -371,17 +381,14 @@ sub login_hash_common {
         key_time           => $self->key_time,
         key_save           => $self->key_save,
         key_expires_min    => $self->key_expires_min,
         key_time           => $self->key_time,
         key_save           => $self->key_save,
         key_expires_min    => $self->key_expires_min,
-        key_payload        => $self->key_payload,
         key_redirect       => $self->key_redirect,
         form_name          => $self->form_name,
         script_name        => $self->script_name,
         path_info          => $self->path_info,
         md5_js_path        => $self->js_uri_path ."/CGI/Ex/md5.js",
         key_redirect       => $self->key_redirect,
         form_name          => $self->form_name,
         script_name        => $self->script_name,
         path_info          => $self->path_info,
         md5_js_path        => $self->js_uri_path ."/CGI/Ex/md5.js",
-        use_plaintext      => $self->use_plaintext,
         $self->key_user    => $data->{'user'} || '',
         $self->key_pass    => '', # don't allow for this to get filled into the form
         $self->key_time    => $self->server_time,
         $self->key_user    => $data->{'user'} || '',
         $self->key_pass    => '', # don't allow for this to get filled into the form
         $self->key_time    => $self->server_time,
-        $self->key_payload => $self->generate_payload({%$data, login_form => 1}),
         $self->key_expires_min => $self->expires_min,
         text_user          => $self->text_user,
         text_pass          => $self->text_pass,
         $self->key_expires_min => $self->expires_min,
         text_user          => $self->text_user,
         text_pass          => $self->text_pass,
@@ -541,9 +548,10 @@ sub verify_password {
             }
         }
 
             }
         }
 
-    ### looks like a normal cram
+    ### looks like a simple_cram
     } elsif ($data->{'cram_time'}) {
     } elsif ($data->{'cram_time'}) {
-        $data->add_data(type => 'cram');
+        $data->add_data(type => 'simple_cram');
+        die "Type simple_cram disabled during verify_password" if $self->disable_simple_cram;
         my $real = $pass =~ /^[a-f0-9]{32}$/ ? lc($pass) : md5_hex($pass);
         my $str  = join("/", @{$data}{qw(user cram_time expires_min payload)});
         my $sum  = md5_hex($str .'/'. $real);
         my $real = $pass =~ /^[a-f0-9]{32}$/ ? lc($pass) : md5_hex($pass);
         my $str  = join("/", @{$data}{qw(user cram_time expires_min payload)});
         my $sum  = md5_hex($str .'/'. $real);
@@ -595,7 +603,7 @@ sub generate_token {
         my $pass = defined($data->{'test_pass'}) ? $data->{'test_pass'} : $data->{'real_pass'};
         $token = $data->{'user'} .'/'. $pass;
 
         my $pass = defined($data->{'test_pass'}) ? $data->{'test_pass'} : $data->{'real_pass'};
         $token = $data->{'user'} .'/'. $pass;
 
-    ### all other types go to cram - secure_hash_cram, cram, plaintext and md5
+    ### all other types go to cram - secure_hash_cram, simple_cram, plaintext and md5
     } else {
         my $user = $data->{'user'} || die "Missing user";
         my $real = defined($data->{'real_pass'})   ? ($data->{'real_pass'} =~ /^[a-f0-9]{32}$/ ? lc($data->{'real_pass'}) : md5_hex($data->{'real_pass'}))
     } else {
         my $user = $data->{'user'} || die "Missing user";
         my $real = defined($data->{'real_pass'})   ? ($data->{'real_pass'} =~ /^[a-f0-9]{32}$/ ? lc($data->{'real_pass'}) : md5_hex($data->{'real_pass'}))
@@ -606,7 +614,7 @@ sub generate_token {
         die "User can not contain a \"/\."                                           if $user =~ m|/|;
 
         my $array;
         die "User can not contain a \"/\."                                           if $user =~ m|/|;
 
         my $array;
-        if (! $data->{'prefer_cram'}
+        if (! $data->{'prefer_simple_cram'}
             && ($array = eval { $self->secure_hash_keys })
             && @$array) {
             my $rand1 = int(rand @$array);
             && ($array = eval { $self->secure_hash_keys })
             && @$array) {
             my $rand1 = int(rand @$array);
@@ -615,6 +623,7 @@ sub generate_token {
             my $sum = md5_hex($str .'/'. $real .('/sh.'.$array->[$rand1].'.'.$rand2));
             $token  = $str .'/'. $sum . '/sh.'.$rand1.'.'.$rand2;
         } else {
             my $sum = md5_hex($str .'/'. $real .('/sh.'.$array->[$rand1].'.'.$rand2));
             $token  = $str .'/'. $sum . '/sh.'.$rand1.'.'.$rand2;
         } else {
+            die "Type simple_cram disabled during generate_token" if $self->disable_simple_cram;
             my $str = join("/", $user, $self->server_time, $exp, $load);
             my $sum = md5_hex($str .'/'. $real);
             $token  = $str .'/'. $sum;
             my $str = join("/", $user, $self->server_time, $exp, $load);
             my $sum = md5_hex($str .'/'. $real);
             $token  = $str .'/'. $sum;
@@ -737,7 +746,6 @@ sub login_form {
     <span class="login_error">[% error %]</span>
     <form class="login_form" name="[% form_name %]" method="POST" action="[% script_name %][% path_info %]">
     <input type="hidden" name="[% key_redirect %]" value="">
     <span class="login_error">[% error %]</span>
     <form class="login_form" name="[% form_name %]" method="POST" action="[% script_name %][% path_info %]">
     <input type="hidden" name="[% key_redirect %]" value="">
-    <input type="hidden" name="[% key_payload %]" value="">
     <input type="hidden" name="[% key_time %]" value="">
     <input type="hidden" name="[% key_expires_min %]" value="">
     <table class="login_table">
     <input type="hidden" name="[% key_time %]" value="">
     <input type="hidden" name="[% key_expires_min %]" value="">
     <table class="login_table">
@@ -774,8 +782,10 @@ sub hide_save   { my $self = shift; return defined($self->{'hide_save'})   ? $se
 sub text_submit { my $self = shift; return defined($self->{'text_submit'}) ? $self->{'text_submit'} : 'Login' }
 
 sub login_script {
 sub text_submit { my $self = shift; return defined($self->{'text_submit'}) ? $self->{'text_submit'} : 'Login' }
 
 sub login_script {
-    return shift->{'login_script'} || q {
-    [%~ IF ! use_plaintext %]
+    my $self = shift;
+    return $self->{'login_script'} if $self->{'login_script'};
+    return '' if $self->use_plaintext || $self->disable_simple_cram;
+    return q {
     <form name="[% form_name %]_jspost" style="margin:0px" method="POST">
     <input type="hidden" name="[% key_user %]"><input type="hidden" name="[% key_redirect %]">
     </form>
     <form name="[% form_name %]_jspost" style="margin:0px" method="POST">
     <input type="hidden" name="[% key_user %]"><input type="hidden" name="[% key_redirect %]">
     </form>
@@ -787,9 +797,8 @@ sub login_script {
       var p = f.[% key_pass %].value;
       var t = f.[% key_time %].value;
       var s = f.[% key_save %] && f.[% key_save %].checked ? -1 : f.[% key_expires_min %].value;
       var p = f.[% key_pass %].value;
       var t = f.[% key_time %].value;
       var s = f.[% key_save %] && f.[% key_save %].checked ? -1 : f.[% key_expires_min %].value;
-      var l = f.[% key_payload %].value;
 
 
-      var str = u+'/'+t+'/'+s+'/'+l;
+      var str = u+'/'+t+'/'+s+'/'+'';
       var sum = document.md5_hex(str +'/' + document.md5_hex(p));
 
       var f2 = document.[% form_name %]_jspost;
       var sum = document.md5_hex(str +'/' + document.md5_hex(p));
 
       var f2 = document.[% form_name %]_jspost;
@@ -800,7 +809,6 @@ sub login_script {
       return false;
     }
     </script>
       return false;
     }
     </script>
-    [% END ~%]
   };
 }
 
   };
 }
 
@@ -887,7 +895,7 @@ CGI::Ex::Auth allows for auto-expiring, safe and easy web based logins.  Auth us
 javascript modules that perform MD5 hashing to cram the password on
 the client side before passing them through the internet.
 
 javascript modules that perform MD5 hashing to cram the password on
 the client side before passing them through the internet.
 
-For the stored cookie you can choose to use cram mechanisms,
+For the stored cookie you can choose to use simple cram mechanisms,
 secure hash cram tokens, auto expiring logins (not cookie based),
 and Crypt::Blowfish protection.  You can also choose to keep
 passwords plaintext and to use perl's crypt for testing
 secure hash cram tokens, auto expiring logins (not cookie based),
 and Crypt::Blowfish protection.  You can also choose to keep
 passwords plaintext and to use perl's crypt for testing
@@ -915,11 +923,11 @@ or may be passed as properties to the new constuctor such as in the following:
         get_pass_by_user => \&my_pass_sub,
         key_user         => 'my_user',
         key_pass         => 'my_pass',
         get_pass_by_user => \&my_pass_sub,
         key_user         => 'my_user',
         key_pass         => 'my_pass',
-        login_template   => \"<form><input name=my_user ... </form>",
+        login_header     => \"<h1>My Login</h1>",
     });
 
 The following methods will look for properties of the same name.  Each of these will be
     });
 
 The following methods will look for properties of the same name.  Each of these will be
-defined separately.
+described separately.
 
     cgix
     cleanup_user
 
     cgix
     cleanup_user
@@ -933,7 +941,6 @@ defined separately.
     key_expires_min
     key_logout
     key_pass
     key_expires_min
     key_logout
     key_pass
-    key_payload
     key_redirect
     key_save
     key_time
     key_redirect
     key_save
     key_time
@@ -950,6 +957,7 @@ defined separately.
     handle_failure
     success_hook
     failure_hook
     handle_failure
     success_hook
     failure_hook
+    logout_hook
     no_cookie_verify
     path_info
     script_name
     no_cookie_verify
     path_info
     script_name
@@ -992,9 +1000,10 @@ Possible arguments are:
                      types.
     payload        - a payload that will be passed to generate_payload and then
                      will be added to cram type tokens.  It cannot contain a /.
                      types.
     payload        - a payload that will be passed to generate_payload and then
                      will be added to cram type tokens.  It cannot contain a /.
-    prefer_cram    - If the secure_hash_keys method returns keys, and it is a non-plaintext
+    prefer_simple_cram
+                   - If the secure_hash_keys method returns keys, and it is a non-plaintext
                      token, generate_token will create a secure_hash_cram.  Set
                      token, generate_token will create a secure_hash_cram.  Set
-                     this value to true to tell it to use a normal cram.  This
+                     this value to true to tell it to use a simple_cram.  This
                      is generally only useful in testing.
 
 The following are types of tokens that can be generated by generate_token.  Each type includes
                      is generally only useful in testing.
 
 The following are types of tokens that can be generated by generate_token.  Each type includes
@@ -1019,7 +1028,7 @@ pseudocode and a sample of a generated that token.
         of the password but the get_pass_by_user hook returns the crypt'ed password, the
         token will not be able to be verified.
 
         of the password but the get_pass_by_user hook returns the crypt'ed password, the
         token will not be able to be verified.
 
-    cram:
+    simple_cram:
         user        := "paul"
         real_pass   := "123qwe"
         server_time := 1148512991         # a time in seconds since epoch
         user        := "paul"
         real_pass   := "123qwe"
         server_time := 1148512991         # a time in seconds since epoch
@@ -1104,17 +1113,14 @@ Passed to the template swapped during login_print.
     key_pass           # $self->key_pass,        # the password fieldname
     key_time           # $self->key_time,        # the server time field name
     key_save           # $self->key_save,        # the save password checkbox field name
     key_pass           # $self->key_pass,        # the password fieldname
     key_time           # $self->key_time,        # the server time field name
     key_save           # $self->key_save,        # the save password checkbox field name
-    key_payload        # $self->key_payload,     # the payload fieldname
     key_redirect       # $self->key_redirect,    # the redirect fieldname
     form_name          # $self->form_name,       # the name of the form
     script_name        # $self->script_name,     # where the server will post back to
     path_info          # $self->path_info,       # $ENV{PATH_INFO} if any
     md5_js_path        # $self->js_uri_path ."/CGI/Ex/md5.js", # script for cramming
     key_redirect       # $self->key_redirect,    # the redirect fieldname
     form_name          # $self->form_name,       # the name of the form
     script_name        # $self->script_name,     # where the server will post back to
     path_info          # $self->path_info,       # $ENV{PATH_INFO} if any
     md5_js_path        # $self->js_uri_path ."/CGI/Ex/md5.js", # script for cramming
-    use_plaintext      # $self->use_plaintext,   # used to avoid cramming
     $self->key_user    # $data->{'user'},        # the username (if any)
     $self->key_pass    # '',                     # intentional blankout
     $self->key_time    # $self->server_time,     # the server's time
     $self->key_user    # $data->{'user'},        # the username (if any)
     $self->key_pass    # '',                     # intentional blankout
     $self->key_time    # $self->server_time,     # the server's time
-    $self->key_payload # $data->{'payload'}      # the payload (if any)
     $self->key_expires_min # $self->expires_min  # how many minutes crams are valid
     text_user          # $self->text_user        # template text Username:
     text_pass          # $self->text_pass        # template text Password:
     $self->key_expires_min # $self->expires_min  # how many minutes crams are valid
     text_user          # $self->text_user        # template text Username:
     text_pass          # $self->text_pass        # template text Password:
@@ -1317,6 +1323,18 @@ The text items shown in the default login template.  The default values are:
     text_pass  "Password:"
     text_save  "Save Password ?"
 
     text_pass  "Password:"
     text_save  "Save Password ?"
 
+=item C<disable_simple_cram>
+
+Disables simple cram type from being an available type. Default is
+false.  If set, then one of use_plaintext, use_crypt, or
+secure_hash_keys should be set.  Setting this option allows for
+payloads to be generated by the server only - otherwise a user who
+understands the algorithm could generate a valid simple_cram cookie
+with a custom payload.
+
+Another option would be to only accept payloads from tokens if use_blowfish
+is set and armor was equal to "blowfish."
+
 =back
 
 =head1 LICENSE
 =back
 
 =head1 LICENSE
index 0b13ca86a85db7b723659055d8d784305ffbfbcb..f635f201612f8e7babf9f5edf2b11705441e6c49 100644 (file)
@@ -29,7 +29,7 @@ use vars qw($VERSION
             );
 @EXPORT_OK = qw(conf_read conf_write in_cache);
 
             );
 @EXPORT_OK = qw(conf_read conf_write in_cache);
 
-$VERSION = '2.20';
+$VERSION = '2.21';
 
 $DEFAULT_EXT = 'conf';
 
 
 $DEFAULT_EXT = 'conf';
 
index a87f50097e7348cc2bbf17c3b21ffa15373fbbbe..4f3aa7295796187311919300f964832f30107846 100644 (file)
@@ -23,7 +23,7 @@ use CGI::Ex;
 use CGI::Ex::Dump qw(debug ctrace dex_html);
 
 BEGIN {
 use CGI::Ex::Dump qw(debug ctrace dex_html);
 
 BEGIN {
-  $VERSION = '2.20';
+  $VERSION = '2.21';
   $SHOW_TRACE = 0      if ! defined $SHOW_TRACE;
   $IGNORE_EVAL = 0     if ! defined $IGNORE_EVAL;
   $EXTENDED_ERRORS = 1 if ! defined $EXTENDED_ERRORS;
   $SHOW_TRACE = 0      if ! defined $SHOW_TRACE;
   $IGNORE_EVAL = 0     if ! defined $IGNORE_EVAL;
   $EXTENDED_ERRORS = 1 if ! defined $EXTENDED_ERRORS;
index d83d6c2cab8edb190f4225c918d65538eea18b5f..796b83eb68cb8ddc16b35021bf669884ff1f46c2 100644 (file)
@@ -17,7 +17,7 @@ use vars qw(@ISA @EXPORT @EXPORT_OK $VERSION
 use strict;
 use Exporter;
 
 use strict;
 use Exporter;
 
-$VERSION   = '2.20';
+$VERSION   = '2.21';
 @ISA       = qw(Exporter);
 @EXPORT    = qw(dex dex_warn dex_text dex_html ctrace dex_trace);
 @EXPORT_OK = qw(dex dex_warn dex_text dex_html ctrace dex_trace debug);
 @ISA       = qw(Exporter);
 @EXPORT    = qw(dex dex_warn dex_text dex_html ctrace dex_trace);
 @EXPORT_OK = qw(dex dex_warn dex_text dex_html ctrace dex_trace debug);
index c4ab9f4621910c0870c6ff93893277a00c24f32b..cbf38de1947807e378e3ad25e39a127f86c28e48 100644 (file)
@@ -24,7 +24,7 @@ use vars qw($VERSION
 use base qw(Exporter);
 
 BEGIN {
 use base qw(Exporter);
 
 BEGIN {
-    $VERSION   = '2.20';
+    $VERSION   = '2.21';
     @EXPORT    = qw(form_fill);
     @EXPORT_OK = qw(fill form_fill html_escape get_tagval_by_key swap_tagval_by_key);
 };
     @EXPORT    = qw(form_fill);
     @EXPORT_OK = qw(fill form_fill html_escape get_tagval_by_key swap_tagval_by_key);
 };
index f212ec75990e69995511889e996b66522d690573..0c2852c63f81a61ac6b1d2cd3adaa9883c41366c 100644 (file)
@@ -17,7 +17,7 @@ use strict;
 use base qw(Exporter);
 
 BEGIN {
 use base qw(Exporter);
 
 BEGIN {
-    $VERSION  = '2.20';
+    $VERSION  = '2.21';
 
     @EXPORT = qw(JSONDump);
     @EXPORT_OK = @EXPORT;
 
     @EXPORT = qw(JSONDump);
     @EXPORT_OK = @EXPORT;
index 715dc19290e7a1f6e8cc2a63b93c9c9fe91c75fb..57ffa0e14cddba3341179358cf53b7b7e69f2f0e 100644 (file)
@@ -25,7 +25,7 @@ use vars qw($VERSION
             $VOBJS
             );
 
             $VOBJS
             );
 
-$VERSION = '2.20';
+$VERSION = '2.21';
 
 ### install true symbol table aliases that can be localized
 *QR_PRIVATE        = *Template::Alloy::QR_PRIVATE;
 
 ### install true symbol table aliases that can be localized
 *QR_PRIVATE        = *Template::Alloy::QR_PRIVATE;
index 18a350192a13064782302d62875e2289bbf758a2..19488728a5993b38b6b8e04718006571e5790336 100644 (file)
@@ -22,7 +22,7 @@ use vars qw($VERSION
             @UNSUPPORTED_BROWSERS
             );
 
             @UNSUPPORTED_BROWSERS
             );
 
-$VERSION = '2.20';
+$VERSION = '2.21';
 
 $DEFAULT_EXT   = 'val';
 $QR_EXTRA      = qr/^(\w+_error|as_(array|string|hash)_\w+|no_\w+)/;
 
 $DEFAULT_EXT   = 'val';
 $QR_EXTRA      = qr/^(\w+_error|as_(array|string|hash)_\w+|no_\w+)/;
This page took 0.045319 seconds and 4 git commands to generate.