Skip to content

Commit 9147df2

Browse files
committed
Correct read/write incompatibility with compliant CDB files.
This fixes a bug introduced in 1.02 which accidentally changed the hash algorithm due to a casting error. Added xt tests to try to test binary regressions with 0.96 in the future. Fixes #12
1 parent 668c4d5 commit 9147df2

File tree

6 files changed

+84
-1
lines changed

6 files changed

+84
-1
lines changed

.github/workflows/testsuite.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ jobs:
3030
run: perl -I$(pwd) Makefile.PL
3131
- name: make test
3232
run: make test
33+
- name: Extended Tests
34+
run: prove -b xt/*.t
3335

3436
linux:
3537
name: "linux ${{ matrix.perl-version }}"
@@ -76,6 +78,8 @@ jobs:
7678
- run: perl Makefile.PL
7779
- run: make
7880
- run: make test
81+
- name: Extended Tests
82+
run: prove -b xt/*.t
7983

8084
macOS:
8185
needs: [ubuntu, linux]
@@ -102,6 +106,8 @@ jobs:
102106
- run: perl Makefile.PL
103107
- run: make
104108
- run: make test
109+
- name: Extended Tests
110+
run: prove -b xt/*.t
105111

106112
windows:
107113
needs: [ubuntu, linux]
@@ -126,3 +132,5 @@ jobs:
126132
run: make
127133
- name: Run Tests
128134
run: make test
135+
- name: Extended Tests
136+
run: prove -b xt/*.t

CDB_File.xs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ static int cdb_make_addend(cdb_make *c, unsigned int keylen, unsigned int datale
188188

189189
#define CDB_HASHSTART 5381
190190

191-
#define cdb_hashadd(hh, cc) ((hh + (hh << 5)) ^ cc)
191+
#define cdb_hashadd(hh, cc) ((hh + (hh << 5)) ^ (unsigned char) cc)
192192

193193
static U32 cdb_hash(char *buf, unsigned int len) {
194194
U32 h;

Changelog

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
Revision history for Perl extension CDB_File.
22

3+
1.03 - Todd Rinaldo <toddr@cpan.org> 2020-11-13
4+
- Fix incompatibility with CDB files due to accidental algorithm change.
5+
- Add xt tests for 0.96 databases to assure this does not happen again.
6+
37
1.02 - Todd Rinaldo <toddr@cpan.org> 2020-01-29
48
- Invoke new as a class method in docs and practice.
59
- Add support for COW PVs when returning key values. This will hopefully

xt/compatibility.cdb

12.2 KB
Binary file not shown.

xt/compatibility0.96.t

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#!perl
2+
3+
use strict;
4+
use warnings;
5+
6+
use Test::More tests => 304;
7+
8+
use CDB_File ();
9+
10+
my $file = 'xt/compatibility.cdb';
11+
our %cdb;
12+
tie %cdb, "CDB_File", $file;
13+
14+
note "UTF8 test";
15+
my $utf8_key = '“Copyright © ”';
16+
my $utf8_value = '“Trademark ™ ”';
17+
is( $cdb{$utf8_key}, $utf8_value, "UTF8 key fetches." );
18+
19+
note "Random keys";
20+
my @keys = keys %cdb;
21+
22+
my $empty_keys;
23+
foreach my $key (@keys) {
24+
my $value = $cdb{$key};
25+
isnt( $value, undef, "Fetched key isn't undef" );
26+
$empty_keys++ if ( $value eq '' );
27+
}
28+
29+
is( $empty_keys, 15, "15 of the keys were an empty string" );

xt/generate_test_database.pl

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#!perl
2+
3+
use strict;
4+
use warnings;
5+
6+
use blib;
7+
use CDB_File ();
8+
9+
open( my $urand_fh, '<', '/dev/urandom' ) or die("Need /dev/urandom to run this utility");
10+
11+
$CDB_File::VERSION eq '0.96' or die("This utility is meant to generate a CDB File on 0.96. You need to have that installed");
12+
13+
my $file = 'xt/compatibility.cdb';
14+
15+
my $utf8_key = '“Copyright © ”';
16+
my $utf8_value = '“Trademark ™ ”';
17+
18+
my $cdb_ver = $CDB_File::VERSION;
19+
20+
unlink $file;
21+
my $cdb = CDB_File->new( $file, "$file.$$" ) or die $!;
22+
$cdb->insert( $utf8_key, $utf8_value );
23+
foreach my $step ( 1 .. 300 ) {
24+
my $key = rnd_str();
25+
my $value = rnd_str();
26+
27+
# Inject a few values with an empty string.
28+
$value = '' if ( $step % 20 == 0 );
29+
30+
$cdb->insert( $key, $value );
31+
}
32+
33+
$cdb->insert( '', 'empty' );
34+
$cdb->finish;
35+
36+
sub rnd_str {
37+
my $len = int( rand(10) ) + 1;
38+
my $buffer;
39+
read( $urand_fh, $buffer, $len );
40+
41+
return $buffer;
42+
}

0 commit comments

Comments
 (0)