From 38d25d7458526c3dbf15b4935e5c9d736ef4209f Mon Sep 17 00:00:00 2001 From: ylavic Date: Thu, 6 Dec 2018 00:48:47 +0100 Subject: [PATCH] Fix FileReadStream::Peek4(). Until Read() reaches EOF, Peek4() must not take off by one in bufferLast_ into account; otherwise a buffer of size exactly 4 always returns NULL. --- bin/data/abcde.txt | 1 + include/rapidjson/filereadstream.h | 2 +- test/unittest/filestreamtest.cpp | 45 +++++++++++++++++++++++++++++- 3 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 bin/data/abcde.txt diff --git a/bin/data/abcde.txt b/bin/data/abcde.txt new file mode 100644 index 0000000..6a81654 --- /dev/null +++ b/bin/data/abcde.txt @@ -0,0 +1 @@ +abcde \ No newline at end of file diff --git a/include/rapidjson/filereadstream.h b/include/rapidjson/filereadstream.h index f1bfb7d..6b34370 100644 --- a/include/rapidjson/filereadstream.h +++ b/include/rapidjson/filereadstream.h @@ -59,7 +59,7 @@ public: // For encoding detection only. const Ch* Peek4() const { - return (current_ + 4 <= bufferLast_) ? current_ : 0; + return (current_ + 4 - !eof_ <= bufferLast_) ? current_ : 0; } private: diff --git a/test/unittest/filestreamtest.cpp b/test/unittest/filestreamtest.cpp index a38133f..0e243ab 100644 --- a/test/unittest/filestreamtest.cpp +++ b/test/unittest/filestreamtest.cpp @@ -21,7 +21,7 @@ using namespace rapidjson; class FileStreamTest : public ::testing::Test { public: - FileStreamTest() : filename_(), json_(), length_() {} + FileStreamTest() : filename_(), json_(), length_(), abcde_() {} virtual ~FileStreamTest(); virtual void SetUp() { @@ -49,6 +49,24 @@ public: size_t readLength = fread(json_, 1, length_, fp); json_[readLength] = '\0'; fclose(fp); + + const char *abcde_paths[] = { + "data/abcde.txt", + "bin/data/abcde.txt", + "../bin/data/abcde.txt", + "../../bin/data/abcde.txt", + "../../../bin/data/abcde.txt" + }; + fp = 0; + for (size_t i = 0; i < sizeof(abcde_paths) / sizeof(abcde_paths[0]); i++) { + fp = fopen(abcde_paths[i], "rb"); + if (fp) { + abcde_ = abcde_paths[i]; + break; + } + } + ASSERT_TRUE(fp != 0); + fclose(fp); } virtual void TearDown() { @@ -64,6 +82,7 @@ protected: const char* filename_; char *json_; size_t length_; + const char* abcde_; }; FileStreamTest::~FileStreamTest() {} @@ -86,6 +105,30 @@ TEST_F(FileStreamTest, FileReadStream) { fclose(fp); } +TEST_F(FileStreamTest, FileReadStream_Peek4) { + FILE *fp = fopen(abcde_, "rb"); + ASSERT_TRUE(fp != 0); + char buffer[4]; + FileReadStream s(fp, buffer, sizeof(buffer)); + + const char* c = s.Peek4(); + for (int i = 0; i < 4; i++) + EXPECT_EQ('a' + i, c[i]); + EXPECT_EQ(0u, s.Tell()); + + for (int i = 0; i < 5; i++) { + EXPECT_EQ(static_cast(i), s.Tell()); + EXPECT_EQ('a' + i, s.Peek()); + EXPECT_EQ('a' + i, s.Peek()); + EXPECT_EQ('a' + i, s.Take()); + } + EXPECT_EQ(5u, s.Tell()); + EXPECT_EQ(0, s.Peek()); + EXPECT_EQ(0, s.Take()); + + fclose(fp); +} + TEST_F(FileStreamTest, FileWriteStream) { char filename[L_tmpnam]; FILE* fp = TempFile(filename);