diff --git a/authfile.c b/authfile.c index b6407e59b..98ad81117 100644 --- a/authfile.c +++ b/authfile.c @@ -41,10 +41,13 @@ enum authfile_ret authfile_load(const char *file) { return AUTHFILE_STATFAIL; } - auth_data = calloc(1, sb.st_size + 1); + auth_data = calloc(1, sb.st_size + 2); char *auth_cur = auth_data; - char *auth_end = auth_data + sb.st_size; + // fgets will stop at EOF or a newline, reading at most one bytes less + // than the size limit. If a user supplies a file without an ending + // newline we will end up chopping the last character of the password. + char *auth_end = auth_data + sb.st_size + 1; auth_t *entry_cur = auth_entries; int used = 0; diff --git a/t/ascii-auth2.t b/t/ascii-auth2.t new file mode 100644 index 000000000..1cfd03e3e --- /dev/null +++ b/t/ascii-auth2.t @@ -0,0 +1,25 @@ +#!/usr/bin/env perl +# Testing for single-line authfiles with no newline at the end. + +use strict; +use Test::More tests => 4; +use FindBin qw($Bin); +use lib "$Bin/lib"; +use MemcachedTest; + +my $server = new_memcached("-Y $Bin/authfile2 -U 0"); +my $sock = $server->sock; + +# Fail to authenticate. +print $sock "set foo 0 0 7\r\nfoo bab\r\n"; +like(scalar <$sock>, qr/CLIENT_ERROR/, "failed to authenticate"); + +# Try for real. +print $sock "set foo 0 0 7\r\nfoo bar\r\n"; +like(scalar <$sock>, qr/STORED/, "authenticated?"); + +print $sock "set toast 0 0 2\r\nhi\r\n"; +like(scalar <$sock>, qr/STORED/, "stored an item that didn't look like user/pass"); + +mem_get_is($sock, "toast", "hi"); + diff --git a/t/authfile2 b/t/authfile2 new file mode 100644 index 000000000..ed3b07fae --- /dev/null +++ b/t/authfile2 @@ -0,0 +1 @@ +foo:bar \ No newline at end of file diff --git a/t/whitespace.t b/t/whitespace.t index 68e82a9d1..6b0368654 100755 --- a/t/whitespace.t +++ b/t/whitespace.t @@ -20,6 +20,7 @@ BEGIN { push(@exempted, glob("*.orig")); push(@exempted, glob(".*.swp")); push(@exempted, glob("queue.h")); + push(@exempted, glob("t/authfile2")); my %exempted_hash = map { $_ => 1 } @exempted; my @stuff = split /\0/, `git ls-files -z -c -m -o --exclude-standard`;