update_engine: Merge contiguous operations (reprise).

This is reapplying CL:269604 with a small fix that prevents it from
adding spurious src_length fields when merging payload operations. This
also revises relevant unit tests to catch the said error. The original
change is described below.

Merges operations of type SOURCE_COPY, REPLACE, or REPLACE_BZ if they
have the same type, are contiguous, have only one destination extent,
and their combined block count does not exceed the chunk size.

BUG=chromium:461651
BUG=chromium:486497
TEST=Unit test (fails before fix, passes after)
TEST=Trybot

Change-Id: I9f3d7f653454e27177428f2d7c0e6485184a7f8b
Reviewed-on: https://chromium-review.googlesource.com/270268
Trybot-Ready: Gilad Arnold <garnold@chromium.org>
Tested-by: Gilad Arnold <garnold@chromium.org>
Reviewed-by: Don Garrett <dgarrett@chromium.org>
Commit-Queue: Gilad Arnold <garnold@chromium.org>
diff --git a/utils.cc b/utils.cc
index b25b602..1e94ffa 100644
--- a/utils.cc
+++ b/utils.cc
@@ -1676,7 +1676,7 @@
   return false;
 }
 
-bool ReadExtents(const std::string& path, vector<Extent>* extents,
+bool ReadExtents(const std::string& path, const vector<Extent>& extents,
                  chromeos::Blob* out_data, ssize_t out_data_size,
                  size_t block_size) {
   chromeos::Blob data(out_data_size);
@@ -1685,7 +1685,7 @@
   TEST_AND_RETURN_FALSE_ERRNO(fd >= 0);
   ScopedFdCloser fd_closer(&fd);
 
-  for (const Extent& extent : *extents) {
+  for (const Extent& extent : extents) {
     ssize_t bytes_read_this_iteration = 0;
     ssize_t bytes = extent.num_blocks() * block_size;
     TEST_AND_RETURN_FALSE(bytes_read + bytes <= out_data_size);