Add some more checkings to the DiffEncoder.

Check that we don't attempt to use the region outside the old file.
While this is supported by our decoder, there's no reason why we should
do that and it often means a bug in the encoder.

Bug: None
Test: Added unittests that would fail without the fixes.
Change-Id: Ifd6d8763ae4e6b3f29a5a1289f22900a278dd1b0
diff --git a/diff_encoder_unittest.cc b/diff_encoder_unittest.cc
index 3bbce87..e3b3747 100644
--- a/diff_encoder_unittest.cc
+++ b/diff_encoder_unittest.cc
@@ -4,6 +4,7 @@
 
 #include "bsdiff/diff_encoder.h"
 
+#include <memory>
 #include <vector>
 
 #include <gtest/gtest.h>
@@ -25,7 +26,13 @@
 
 class DiffEncoderTest : public testing::Test {
  protected:
-  void SetUp() { EXPECT_TRUE(fake_patch_.Init()); }
+  void SetUp() {
+    EXPECT_TRUE(fake_patch_.Init());
+    // By default, set the encoder to kHelloWorld to kHelloWorld.
+    diff_encoder_.reset(new DiffEncoder(&fake_patch_, kHelloWorld,
+                                        sizeof(kHelloWorld), kHelloWorld,
+                                        sizeof(kHelloWorld)));
+  }
 
   FakePatchWriter fake_patch_;
   std::unique_ptr<DiffEncoder> diff_encoder_;
@@ -59,9 +66,6 @@
 }
 
 TEST_F(DiffEncoderTest, AllInDiffStreamTest) {
-  diff_encoder_.reset(new DiffEncoder(&fake_patch_, kHelloWorld,
-                                      sizeof(kHelloWorld), kHelloWorld,
-                                      sizeof(kHelloWorld)));
   EXPECT_TRUE(
       diff_encoder_->AddControlEntry(ControlEntry(sizeof(kHelloWorld), 0, 0)));
   EXPECT_TRUE(diff_encoder_->Close());
@@ -71,4 +75,36 @@
   EXPECT_TRUE(fake_patch_.extra_stream().empty());
 }
 
+TEST_F(DiffEncoderTest, OldPosNegativeErrorTest) {
+  // Referencing negative values in oldpos is fine, until you use them.
+  EXPECT_TRUE(diff_encoder_->AddControlEntry(ControlEntry(0, 0, -5)));
+  EXPECT_TRUE(diff_encoder_->AddControlEntry(ControlEntry(0, 0, 2)));
+  EXPECT_FALSE(diff_encoder_->AddControlEntry(ControlEntry(1, 0, 0)));
+}
+
+// Test that using an oldpos past the end of the file fails.
+TEST_F(DiffEncoderTest, OldPosTooBigErrorTest) {
+  EXPECT_TRUE(
+      diff_encoder_->AddControlEntry(ControlEntry(0, 0, sizeof(kHelloWorld))));
+  EXPECT_FALSE(diff_encoder_->AddControlEntry(ControlEntry(1, 0, 0)));
+}
+
+// Test that diffing against a section of the old file past the end of the file
+// fails.
+TEST_F(DiffEncoderTest, OldPosPlusSizeTooBigErrorTest) {
+  // The oldpos is set to a range inside the word, the we try to copy past the
+  // end of it.
+  EXPECT_TRUE(diff_encoder_->AddControlEntry(
+      ControlEntry(0, 0, sizeof(kHelloWorld) - 3)));
+  EXPECT_FALSE(
+      diff_encoder_->AddControlEntry(ControlEntry(sizeof(kHelloWorld), 0, 0)));
+}
+
+TEST_F(DiffEncoderTest, ExtraStreamTooBigErrorTest) {
+  EXPECT_TRUE(diff_encoder_->AddControlEntry(ControlEntry(3, 0, 0)));
+  // This writes too many bytes in the stream because we already have 3 bytes.
+  EXPECT_FALSE(
+      diff_encoder_->AddControlEntry(ControlEntry(0, sizeof(kHelloWorld), 0)));
+}
+
 }  // namespace bsdiff