[M108 Migration][VD] Support set time and time zone offset
[platform/framework/web/chromium-efl.git] / base / base64url.cc
1 // Copyright 2015 The Chromium Authors
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/base64url.h"
6
7 #include <stddef.h>
8
9 #include "base/base64.h"
10 #include "base/numerics/safe_math.h"
11 #include "base/strings/string_util.h"
12 #include "third_party/modp_b64/modp_b64.h"
13
14 namespace base {
15
16 const char kPaddingChar = '=';
17
18 // Base64url maps {+, /} to {-, _} in order for the encoded content to be safe
19 // to use in a URL. These characters will be translated by this implementation.
20 const char kBase64Chars[] = "+/";
21 const char kBase64UrlSafeChars[] = "-_";
22
23 void Base64UrlEncode(const StringPiece& input,
24                      Base64UrlEncodePolicy policy,
25                      std::string* output) {
26   Base64Encode(input, output);
27
28   ReplaceChars(*output, "+", "-", output);
29   ReplaceChars(*output, "/", "_", output);
30
31   switch (policy) {
32     case Base64UrlEncodePolicy::INCLUDE_PADDING:
33       // The padding included in |*output| will not be amended.
34       break;
35     case Base64UrlEncodePolicy::OMIT_PADDING:
36       // The padding included in |*output| will be removed.
37       const size_t last_non_padding_pos =
38           output->find_last_not_of(kPaddingChar);
39       if (last_non_padding_pos != std::string::npos)
40         output->resize(last_non_padding_pos + 1);
41
42       break;
43   }
44 }
45
46 bool Base64UrlDecode(const StringPiece& input,
47                      Base64UrlDecodePolicy policy,
48                      std::string* output) {
49   // Characters outside of the base64url alphabet are disallowed, which includes
50   // the {+, /} characters found in the conventional base64 alphabet.
51   if (input.find_first_of(kBase64Chars) != std::string::npos)
52     return false;
53
54   const size_t required_padding_characters = input.size() % 4;
55   const bool needs_replacement =
56       input.find_first_of(kBase64UrlSafeChars) != std::string::npos;
57
58   switch (policy) {
59     case Base64UrlDecodePolicy::REQUIRE_PADDING:
60       // Fail if the required padding is not included in |input|.
61       if (required_padding_characters > 0)
62         return false;
63       break;
64     case Base64UrlDecodePolicy::IGNORE_PADDING:
65       // Missing padding will be silently appended.
66       break;
67     case Base64UrlDecodePolicy::DISALLOW_PADDING:
68       // Fail if padding characters are included in |input|.
69       if (input.find_first_of(kPaddingChar) != std::string::npos)
70         return false;
71       break;
72   }
73
74   // If the string either needs replacement of URL-safe characters to normal
75   // base64 ones, or additional padding, a copy of |input| needs to be made in
76   // order to make these adjustments without side effects.
77   if (required_padding_characters > 0 || needs_replacement) {
78     std::string base64_input;
79
80     CheckedNumeric<size_t> base64_input_size = input.size();
81     if (required_padding_characters > 0)
82       base64_input_size += 4 - required_padding_characters;
83
84     base64_input.reserve(base64_input_size.ValueOrDie());
85     base64_input.append(input.data(), input.size());
86
87     // Substitute the base64url URL-safe characters to their base64 equivalents.
88     ReplaceChars(base64_input, "-", "+", &base64_input);
89     ReplaceChars(base64_input, "_", "/", &base64_input);
90
91     // Append the necessary padding characters.
92     base64_input.resize(base64_input_size.ValueOrDie(), '=');
93
94     return Base64Decode(base64_input, output);
95   }
96
97   return Base64Decode(input, output);
98 }
99
100 }  // namespace base