[email protected] | 90e800c | 2012-06-12 23:11:00 | [diff] [blame] | 1 | // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
[email protected] | 8703b2b | 2011-03-15 09:51:50 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
| 5 | #include "base/value_conversions.h" |
| 6 | |
avi | 9b6f4293 | 2015-12-26 22:15:14 | [diff] [blame] | 7 | #include <stdint.h> |
| 8 | |
yucliu | d62536a | 2017-08-01 06:06:30 | [diff] [blame] | 9 | #include <algorithm> |
[email protected] | c014f2b3 | 2013-09-03 23:29:12 | [diff] [blame] | 10 | #include <string> |
yucliu | d62536a | 2017-08-01 06:06:30 | [diff] [blame] | 11 | #include <vector> |
[email protected] | c014f2b3 | 2013-09-03 23:29:12 | [diff] [blame] | 12 | |
[email protected] | 5799981 | 2013-02-24 05:40:52 | [diff] [blame] | 13 | #include "base/files/file_path.h" |
vabr | bce355c | 2017-03-23 18:52:43 | [diff] [blame] | 14 | #include "base/memory/ptr_util.h" |
[email protected] | dfa049e | 2013-02-07 02:57:22 | [diff] [blame] | 15 | #include "base/strings/string_number_conversions.h" |
[email protected] | 8f9a3a5 | 2013-06-28 15:14:18 | [diff] [blame] | 16 | #include "base/time/time.h" |
yucliu | d62536a | 2017-08-01 06:06:30 | [diff] [blame] | 17 | #include "base/unguessable_token.h" |
[email protected] | 8703b2b | 2011-03-15 09:51:50 | [diff] [blame] | 18 | #include "base/values.h" |
| 19 | |
| 20 | namespace base { |
yucliu | d62536a | 2017-08-01 06:06:30 | [diff] [blame] | 21 | namespace { |
| 22 | // Helper for serialize/deserialize UnguessableToken. |
| 23 | union UnguessableTokenRepresentation { |
| 24 | struct Field { |
| 25 | uint64_t high; |
| 26 | uint64_t low; |
| 27 | } field; |
| 28 | |
| 29 | uint8_t buffer[sizeof(Field)]; |
| 30 | }; |
| 31 | } // namespace |
[email protected] | 8703b2b | 2011-03-15 09:51:50 | [diff] [blame] | 32 | |
[email protected] | 8703b2b | 2011-03-15 09:51:50 | [diff] [blame] | 33 | // |Value| internally stores strings in UTF-8, so we have to convert from the |
| 34 | // system native code to UTF-8 and back. |
vabr | bce355c | 2017-03-23 18:52:43 | [diff] [blame] | 35 | std::unique_ptr<Value> CreateFilePathValue(const FilePath& in_value) { |
Jeremy Roman | 9532f25 | 2017-08-16 23:27:24 | [diff] [blame] | 36 | return std::make_unique<Value>(in_value.AsUTF8Unsafe()); |
[email protected] | 8703b2b | 2011-03-15 09:51:50 | [diff] [blame] | 37 | } |
| 38 | |
| 39 | bool GetValueAsFilePath(const Value& value, FilePath* file_path) { |
| 40 | std::string str; |
| 41 | if (!value.GetAsString(&str)) |
| 42 | return false; |
| 43 | if (file_path) |
[email protected] | 4544051 | 2011-11-02 04:55:23 | [diff] [blame] | 44 | *file_path = FilePath::FromUTF8Unsafe(str); |
[email protected] | 8703b2b | 2011-03-15 09:51:50 | [diff] [blame] | 45 | return true; |
| 46 | } |
| 47 | |
[email protected] | 90e800c | 2012-06-12 23:11:00 | [diff] [blame] | 48 | // |Value| does not support 64-bit integers, and doubles do not have enough |
| 49 | // precision, so we store the 64-bit time value as a string instead. |
vabr | bce355c | 2017-03-23 18:52:43 | [diff] [blame] | 50 | std::unique_ptr<Value> CreateTimeDeltaValue(const TimeDelta& time) { |
[email protected] | 90e800c | 2012-06-12 23:11:00 | [diff] [blame] | 51 | std::string string_value = base::Int64ToString(time.ToInternalValue()); |
Jeremy Roman | 9532f25 | 2017-08-16 23:27:24 | [diff] [blame] | 52 | return std::make_unique<Value>(string_value); |
[email protected] | 90e800c | 2012-06-12 23:11:00 | [diff] [blame] | 53 | } |
| 54 | |
[email protected] | 64a82a5 | 2012-06-14 00:30:56 | [diff] [blame] | 55 | bool GetValueAsTimeDelta(const Value& value, TimeDelta* time) { |
[email protected] | 90e800c | 2012-06-12 23:11:00 | [diff] [blame] | 56 | std::string str; |
avi | 9b6f4293 | 2015-12-26 22:15:14 | [diff] [blame] | 57 | int64_t int_value; |
[email protected] | 90e800c | 2012-06-12 23:11:00 | [diff] [blame] | 58 | if (!value.GetAsString(&str) || !base::StringToInt64(str, &int_value)) |
| 59 | return false; |
| 60 | if (time) |
[email protected] | 64a82a5 | 2012-06-14 00:30:56 | [diff] [blame] | 61 | *time = TimeDelta::FromInternalValue(int_value); |
[email protected] | 90e800c | 2012-06-12 23:11:00 | [diff] [blame] | 62 | return true; |
| 63 | } |
| 64 | |
yucliu | d62536a | 2017-08-01 06:06:30 | [diff] [blame] | 65 | std::unique_ptr<Value> CreateUnguessableTokenValue( |
| 66 | const UnguessableToken& token) { |
| 67 | UnguessableTokenRepresentation representation; |
| 68 | representation.field.high = token.GetHighForSerialization(); |
| 69 | representation.field.low = token.GetLowForSerialization(); |
| 70 | |
Jeremy Roman | 9532f25 | 2017-08-16 23:27:24 | [diff] [blame] | 71 | return std::make_unique<Value>( |
yucliu | d62536a | 2017-08-01 06:06:30 | [diff] [blame] | 72 | HexEncode(representation.buffer, sizeof(representation.buffer))); |
| 73 | } |
| 74 | |
| 75 | bool GetValueAsUnguessableToken(const Value& value, UnguessableToken* token) { |
| 76 | if (!value.is_string()) { |
| 77 | return false; |
| 78 | } |
| 79 | |
| 80 | // TODO(dcheng|yucliu): Make a function that accepts non vector variant and |
| 81 | // reads a fixed number of bytes. |
| 82 | std::vector<uint8_t> high_low_bytes; |
| 83 | if (!HexStringToBytes(value.GetString(), &high_low_bytes)) { |
| 84 | return false; |
| 85 | } |
| 86 | |
| 87 | UnguessableTokenRepresentation representation; |
| 88 | if (high_low_bytes.size() != sizeof(representation.buffer)) { |
| 89 | return false; |
| 90 | } |
| 91 | |
| 92 | std::copy(high_low_bytes.begin(), high_low_bytes.end(), |
| 93 | std::begin(representation.buffer)); |
| 94 | *token = UnguessableToken::Deserialize(representation.field.high, |
| 95 | representation.field.low); |
| 96 | return true; |
| 97 | } |
| 98 | |
[email protected] | 8703b2b | 2011-03-15 09:51:50 | [diff] [blame] | 99 | } // namespace base |