IndexedDB: Change Mojo IDBValue.bits type from string to array<uint8>

TL;DR IDBValue.bits was type string which worked until we added a
Mojo Blink variant that introduced a new conversion requirement.
IDBValue.bits is actually a sequence of octets, so use array<uint8>,
instead.

More details:

Chrome's IndexedDB implementation uses a Mojo definition that
specifies the IDBValue struct contains a field |bits|.  The field is
used to represent the data that's written to and read off of disk by
IndexedDB's LevelDB instance.

Previously, the |bits| field was of type string and there were only
content variants of the Mojo C++ bindings for IndexedDB.  This led to
the field only ever being translated to/from std::string.
std::string can contain these raw byte sequences since there are no
constraints placed on the string holding data following any
particular format or validation.

As part of bug 717812 and https://crrev.com/1265900, a new Blink
variant for the IndexedDB Mojo interfaces was added.  The Blink
variant relies on WTF::String instead of std::string, and so the
IDBValue.bits field was translated for that variant to/from
WTF::String.

Mojo's WTF::String traits uses WTF::String::FromUTF8().  As part of
FromUTF8()'s implementation, if the given set of characters contains
invalid UTF-8 data, FromUTF8() will return a null String instance.
The IDBValue.bits field is not restricted just to UTF-8 characters,
and so it always ended up being set to the null String in the traits.

The net result of this bug was that our carriage format changed:

- Chrome with https://crrev.com/1265900 could not read Chrome
  stable's IDB instances

- Chrome without https://crrev.com/1265900 could not read Chrome with
  http://crrev.com/1265900's IDB instances

More about the impact of that bug can be read at
https://crbug.com/899446.

We must observe FromUTF8()'s requirement that we pass only UTF-8
valid data in string types.  We also need to observe that we are in
fact passing raw byte data in the IDBValue.bits field instead of what
both variants would consider as valid strings.

The fix is to change IDBValue.bits from a string type to a type of
array<uint8>.  LevelDB's API requires strings, so in content to/from
the LevelDB instance we must pass in and receive strings.  In Blink,
the data is represented as a WebData instance, which also takes raw
character data.  To support both sides, I've added in-place
conversions to/from std::string and to/from WebData.

Bug: 717812
Change-Id: Iadfbd21be52fc50abc60a2695b95691bc07028e4
Reviewed-on: https://chromium-review.googlesource.com/c/1316444
Commit-Queue: Chase Phillips <cmp@chromium.org>
Reviewed-by: Victor Costan <pwnall@chromium.org>
Reviewed-by: Kentaro Hara <haraken@chromium.org>
Reviewed-by: Daniel Murphy <dmurph@chromium.org>
Reviewed-by: Daniel Cheng <dcheng@chromium.org>
Reviewed-by: Kinuko Yasuda <kinuko@chromium.org>
Reviewed-by: Reilly Grant <reillyg@chromium.org>
Cr-Commit-Position: refs/heads/master@{#605918}
8 files changed