Skip to content

Commit

Permalink
[0.72] Fix Base64 duplicate padding (#12700)
Browse files Browse the repository at this point in the history
* Ensure origin in WebSocket headers (#12643)

* update cgmanifest

* Ensure origin in WebSocket headers

* Use case-insensitive comparison

* Change files

* Assign SetRequestHeader mocks where needed

* Fix Base64 duplicate padding (#12689)

* Remove unused Boost headers from FR module source

* Declare encode/decode base64 utility methods

* Implement Encode methods

* Update packages.lock.json

* Update packages.lock.json

* Use string as return value to ensure lifetime

See https://learn.microsoft.com/en-us/cpp/code-quality/c26816?view=msvc-170

* Apply padding for Boost variant

* Remove decode from base64 wstring variant

* Cover 4*3 (plus empty) cases in unit tests

* Make output padding size match to input size % 4

* clang format

* Implement DecodeBase64

* Replace scattered usage of Boost base64_from_binary

* Remove Boost includes from BaseFrRc

* Change files

* Remove EncodeBase64(wstring_view)

* Add test for non-text values

* Pass string_view by value

* Ensure binary data lifetime in test

* Remove change files

* Change files

* Add missing sstream includes (#12713)

* Add missing sstream includes

- C++17 won't infer the missing entries automatically.

* Change files

* Remove change files
  • Loading branch information
JunielKatarn committed Feb 10, 2024
1 parent 4db77b3 commit f1cb8a4
Show file tree
Hide file tree
Showing 11 changed files with 306 additions and 74 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"type": "patch",
"comment": "Fix Base64 duplicate padding (#12689)",
"packageName": "react-native-windows",
"email": "julio.rocha@microsoft.com",
"dependentChangeType": "patch"
}
7 changes: 6 additions & 1 deletion vnext/Common/Common.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
string literals. It prevents code like
wchar_t* str = L"hello";
from compiling. -->
<AdditionalOptions>%(AdditionalOptions) /Zc:strictStrings</AdditionalOptions>
<AdditionalOptions>%(AdditionalOptions) /Zc:strictStrings /await</AdditionalOptions>
</ClCompile>
<Link>
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
Expand All @@ -78,12 +78,17 @@
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="Unicode.cpp" />
<ClCompile Include="Utilities.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="Unicode.h" />
<ClInclude Include="Utilities.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ItemGroup>
<PackageReference Include="boost" Version="1.76.0.0" />
<PackageReference Include="Microsoft.Windows.CppWinRT" Version="$(CppWinRTVersion)" PrivateAssets="all" />
</ItemGroup>
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
<Target Name="Deploy" />
Expand Down
3 changes: 3 additions & 0 deletions vnext/Common/Common.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
<ClCompile Include="Unicode.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Utilities.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Unicode.h">
Expand Down
59 changes: 59 additions & 0 deletions vnext/Common/Utilities.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

#include "Utilities.h"

// Boost Library
#include <boost/archive/iterators/base64_from_binary.hpp>
#include <boost/archive/iterators/binary_from_base64.hpp>
#include <boost/archive/iterators/ostream_iterator.hpp>
#include <boost/archive/iterators/transform_width.hpp>

// Windows API
#include <winrt/Windows.Security.Cryptography.h>

// Standard Library
#include <sstream>

using std::string;
using std::string_view;
using std::wstring_view;
using winrt::array_view;

using winrt::Windows::Security::Cryptography::BinaryStringEncoding;
using winrt::Windows::Security::Cryptography::CryptographicBuffer;

namespace Microsoft::React::Utilities {

string DecodeBase64(string_view base64) noexcept {
typedef array_view<char const> av_t;
auto bytes = av_t(base64.data(), static_cast<av_t::size_type>(base64.size()));

using namespace boost::archive::iterators;
typedef transform_width<binary_from_base64<const char *>, 8, 6> decode_base64;
std::ostringstream oss;
std::copy(decode_base64(bytes.cbegin()), decode_base64(bytes.cend()), ostream_iterator<char>(oss));

return oss.str();
}

// https://www.boost.org/doc/libs/1_76_0/libs/serialization/doc/dataflow.html
string EncodeBase64(string_view text) noexcept {
typedef array_view<char const> av_t;
auto bytes = av_t(text.data(), static_cast<av_t::size_type>(text.size()));

using namespace boost::archive::iterators;
typedef base64_from_binary<transform_width<const char *, 6, 8>> encode_base64;
std::ostringstream oss;
std::copy(encode_base64(bytes.cbegin()), encode_base64(bytes.cend()), ostream_iterator<char>(oss));

// https://unix.stackexchange.com/questions/631501
auto padLength = (4 - (oss.tellp() % 4)) % 4;
for (auto i = 0; i < padLength; ++i) {
oss << '=';
}

return oss.str();
}

} // namespace Microsoft::React::Utilities
11 changes: 11 additions & 0 deletions vnext/Common/utilities.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
// Licensed under the MIT License.

#pragma once

// Standard Library
#include <string>
#include <type_traits>
#include <utility>

Expand Down Expand Up @@ -37,3 +40,11 @@ constexpr std::size_t ArraySize(T (&)[N]) noexcept {
}

} // namespace Microsoft::Common::Utilities

namespace Microsoft::React::Utilities {

std::string DecodeBase64(std::string_view text) noexcept;

std::string EncodeBase64(std::string_view text) noexcept;

} // namespace Microsoft::React::Utilities

0 comments on commit f1cb8a4

Please sign in to comment.