LP# 953299 - Prevent get/set of invalid cache keys
authorDan Scott <dan@coffeecode.net>
Mon, 21 May 2012 16:18:41 +0000 (12:18 -0400)
committerDan Scott <dan@coffeecode.net>
Mon, 21 May 2012 21:17:44 +0000 (17:17 -0400)
Clients of OpenSRF::Utils::Cache occasionally request cache keys that
contain invalid characters (a particular case is ISBNs that contain
spaces), so strip those out of incoming get/set requests to avoid ugly
memcached errors.

Signed-off-by: Dan Scott <dan@coffeecode.net>
Signed-off-by: Galen Charlton <gmc@esilibrary.com>

src/perl/lib/OpenSRF/Utils/Cache.pm
src/perl/t/09-Utils-Cache.t

index 1fb56a4..53cf966 100644 (file)
@@ -109,6 +109,9 @@ sub new {
 
 sub put_cache {
        my($self, $key, $value, $expiretime ) = @_;
+
+       $key = _clean_cache_key($key);
+
        return undef unless( defined $key and defined $value );
 
        $value = OpenSRF::Utils::JSON->perl2JSON($value);
@@ -155,6 +158,7 @@ sub put_cache {
 
 sub delete_cache {
        my( $self, $key ) = @_;
+       $key = _clean_cache_key($key);
        if(!$key) { return undef; }
        if($self->{persist}){ _load_methods(); }
        $self->{memcache}->delete($key);
@@ -172,6 +176,8 @@ sub delete_cache {
 sub get_cache {
        my($self, $key ) = @_;
 
+       $key = _clean_cache_key($key);
+
        my $val = $self->{memcache}->get( $key );
        return OpenSRF::Utils::JSON->JSON2perl($val) if defined($val);
 
@@ -248,10 +254,29 @@ sub _load_methods {
 }
 
 
+=head2 _clean_cache_key
 
+Try to make the requested cache key conform to memcached's requirements. Per
+https://github.com/memcached/memcached/blob/master/doc/protocol.txt:
 
+"""
+Data stored by memcached is identified with the help of a key. A key
+is a text string which should uniquely identify the data for clients
+that are interested in storing and retrieving it.  Currently the
+length limit of a key is set at 250 characters (of course, normally
+clients wouldn't need to use such long keys); the key must not include
+control characters or whitespace.
+"""
 
+=cut
 
+sub _clean_cache_key {
+    my $key = shift;
+
+    $key =~ s{(\p{Cntrl}|\s)}{}g;
+
+    return $key;
+}
 
 1;
 
index 8d4c85b..07941b7 100644 (file)
@@ -1,7 +1,9 @@
 #!perl -T
 
-use Test::More tests => 1;
+use Test::More tests => 2;
 
 BEGIN {
        use_ok( 'OpenSRF::Utils::Cache' );
 }
+
+is (OpenSRF::Utils::Cache::_clean_cache_key('ac.jacket.large.9780415590211 (hbk.)'), 'ac.jacket.large.9780415590211(hbk.)');