Skip to content

Commit 4ed905a

Browse files
PR comments; return success on EOF for BIO_read_ex
1 parent 0823b01 commit 4ed905a

File tree

3 files changed

+21
-11
lines changed

3 files changed

+21
-11
lines changed

crypto/bio/bio.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ int BIO_read_ex(BIO *bio, void *data, size_t data_len, size_t *read_bytes) {
198198
}
199199

200200
int ret = BIO_read(bio, data, read_len);
201-
if (ret > 0) {
201+
if (ret >= 0) {
202202
*read_bytes = ret;
203203
return 1;
204204
} else {

crypto/bio/bio_test.cc

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1068,18 +1068,23 @@ TEST(BIOTest, ReadWriteEx) {
10681068
bssl::UniquePtr<BIO> bio(BIO_new(BIO_s_mem()));
10691069
ASSERT_TRUE(bio);
10701070

1071-
size_t written = 0;
1071+
// Reading from an initially empty bio should default to returning a error.
1072+
// Check that both |BIO_read| and |BIO_read_ex| fail.
1073+
char buf[32];
1074+
size_t read = 1;
1075+
EXPECT_EQ(BIO_read(bio.get(), buf, sizeof(buf)), -1);
1076+
EXPECT_FALSE(BIO_read_ex(bio.get(), buf, sizeof(buf), &read));
1077+
EXPECT_EQ(read, (size_t)0);
1078+
1079+
// Write and read normally from buffer.
1080+
size_t written = 1;
10721081
ASSERT_TRUE(BIO_write_ex(bio.get(), "abcdef", 6, &written));
10731082
EXPECT_EQ(written, (size_t)6);
1074-
1075-
char buf[32];
1076-
size_t read = 0;
10771083
ASSERT_TRUE(BIO_read_ex(bio.get(), buf, sizeof(buf), &read));
10781084
EXPECT_EQ(read, (size_t)6);
10791085
EXPECT_EQ(Bytes(buf, read), Bytes("abcdef"));
10801086

10811087
// Test NULL |written_bytes| behavior works.
1082-
read = 0;
10831088
ASSERT_TRUE(BIO_write_ex(bio.get(), "ghilmnop", 8, nullptr));
10841089
ASSERT_TRUE(BIO_read_ex(bio.get(), buf, sizeof(buf), &read));
10851090
EXPECT_EQ(read, (size_t)8);
@@ -1090,13 +1095,12 @@ TEST(BIOTest, ReadWriteEx) {
10901095
ASSERT_FALSE(BIO_read_ex(bio.get(), buf, sizeof(buf), nullptr));
10911096

10921097
// Test that |BIO_write/read_ex| align with their non-ex counterparts, when
1093-
// encountering NULL data.
1094-
written = 1;
1098+
// encountering NULL data. EOF in |BIO_read| is indicated by returning 0.
1099+
// In AWS-LC's |BIO_read_ex|, this should return success and set |read| to 0.
10951100
EXPECT_FALSE(BIO_write(bio.get(), nullptr, 0));
10961101
EXPECT_FALSE(BIO_write_ex(bio.get(), nullptr, 0, &written));
10971102
EXPECT_EQ(written, (size_t)0);
1098-
read = 1;
1099-
EXPECT_FALSE(BIO_read(bio.get(), nullptr, 0));
1100-
EXPECT_FALSE(BIO_read_ex(bio.get(), nullptr, 0, &read));
1103+
EXPECT_EQ(BIO_read(bio.get(), nullptr, 0), 0);
1104+
ASSERT_TRUE(BIO_read_ex(bio.get(), nullptr, 0, &read));
11011105
EXPECT_EQ(read, (size_t)0);
11021106
}

include/openssl/bio.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,12 @@ OPENSSL_EXPORT int BIO_read(BIO *bio, void *data, int len);
112112

113113
// BIO_read_ex calls |BIO_read| and stores the number of bytes read in
114114
// |read_bytes|. It returns one on success and zero otherwise.
115+
//
116+
// Note: OpenSSL's |BIO_read_ex| returns zero on EOF. This disallows any
117+
// mechanism to notify the user that an EOF has occurred and renders this API
118+
// unusable. See openssl/openssl#8208.
119+
// |BIO_read_ex| will return one for success and set |read_bytes| to 0 on EOF in
120+
// AWS-LC.
115121
OPENSSL_EXPORT int BIO_read_ex(BIO *bio, void *data, size_t data_len,
116122
size_t *read_bytes);
117123

0 commit comments

Comments
 (0)