react-native-windows 0.72.31 → 0.72.33
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Libraries/Animated/NativeAnimatedHelper.js +6 -3
- package/Libraries/Core/ReactNativeVersion.js +1 -1
- package/Libraries/LogBox/Data/LogBoxData.js +2 -1
- package/Libraries/LogBox/Data/parseLogBoxLog.js +51 -21
- package/Libraries/promiseRejectionTrackingOptions.js +26 -7
- package/PropertySheets/Generated/PackageVersion.g.props +3 -3
- package/Shared/Networking/OriginPolicyHttpFilter.cpp +36 -36
- package/Shared/Networking/OriginPolicyHttpFilter.h +16 -18
- package/Shared/Networking/WinRTHttpResource.cpp +2 -4
- package/package.json +10 -9
|
@@ -562,10 +562,13 @@ function transformDataType(value: number | string): number | string {
|
|
|
562
562
|
if (typeof value !== 'string') {
|
|
563
563
|
return value;
|
|
564
564
|
}
|
|
565
|
-
|
|
565
|
+
|
|
566
|
+
// Normalize degrees and radians to a number expressed in radians
|
|
567
|
+
if (value.endsWith('deg')) {
|
|
566
568
|
const degrees = parseFloat(value) || 0;
|
|
567
|
-
|
|
568
|
-
|
|
569
|
+
return (degrees * Math.PI) / 180.0;
|
|
570
|
+
} else if (value.endsWith('rad')) {
|
|
571
|
+
return parseFloat(value) || 0;
|
|
569
572
|
} else {
|
|
570
573
|
return value;
|
|
571
574
|
}
|
|
@@ -30,6 +30,7 @@ export type LogData = $ReadOnly<{|
|
|
|
30
30
|
message: Message,
|
|
31
31
|
category: Category,
|
|
32
32
|
componentStack: ComponentStack,
|
|
33
|
+
stack?: string,
|
|
33
34
|
|}>;
|
|
34
35
|
|
|
35
36
|
export type Observer = (
|
|
@@ -198,7 +199,7 @@ export function addLog(log: LogData): void {
|
|
|
198
199
|
// otherwise spammy logs would pause rendering.
|
|
199
200
|
setImmediate(() => {
|
|
200
201
|
try {
|
|
201
|
-
const stack = parseErrorStack(errorForStackTrace?.stack);
|
|
202
|
+
const stack = parseErrorStack(log.stack ?? errorForStackTrace?.stack);
|
|
202
203
|
|
|
203
204
|
appendNewLog(
|
|
204
205
|
new LogBoxLog({
|
|
@@ -14,12 +14,38 @@ import type {LogBoxLogData} from './LogBoxLog';
|
|
|
14
14
|
import parseErrorStack from '../../Core/Devtools/parseErrorStack';
|
|
15
15
|
import UTFSequence from '../../UTFSequence';
|
|
16
16
|
import stringifySafe from '../../Utilities/stringifySafe';
|
|
17
|
+
import ansiRegex from 'ansi-regex';
|
|
18
|
+
|
|
19
|
+
const ANSI_REGEX = ansiRegex().source;
|
|
17
20
|
|
|
18
21
|
const BABEL_TRANSFORM_ERROR_FORMAT =
|
|
19
22
|
/^(?:TransformError )?(?:SyntaxError: |ReferenceError: )(.*): (.*) \((\d+):(\d+)\)\n\n([\s\S]+)/;
|
|
23
|
+
|
|
24
|
+
// https://github.com/babel/babel/blob/33dbb85e9e9fe36915273080ecc42aee62ed0ade/packages/babel-code-frame/src/index.ts#L183-L184
|
|
25
|
+
const BABEL_CODE_FRAME_MARKER_PATTERN = new RegExp(
|
|
26
|
+
[
|
|
27
|
+
// Beginning of a line (per 'm' flag)
|
|
28
|
+
'^',
|
|
29
|
+
// Optional ANSI escapes for colors
|
|
30
|
+
`(?:${ANSI_REGEX})*`,
|
|
31
|
+
// Marker
|
|
32
|
+
'>',
|
|
33
|
+
// Optional ANSI escapes for colors
|
|
34
|
+
`(?:${ANSI_REGEX})*`,
|
|
35
|
+
// Left padding for line number
|
|
36
|
+
' +',
|
|
37
|
+
// Line number
|
|
38
|
+
'[0-9]+',
|
|
39
|
+
// Gutter
|
|
40
|
+
' \\|',
|
|
41
|
+
].join(''),
|
|
42
|
+
'm',
|
|
43
|
+
);
|
|
44
|
+
|
|
20
45
|
const BABEL_CODE_FRAME_ERROR_FORMAT =
|
|
21
46
|
// eslint-disable-next-line no-control-regex
|
|
22
47
|
/^(?:TransformError )?(?:.*):? (?:.*?)(\/.*): ([\s\S]+?)\n([ >]{2}[\d\s]+ \|[\s\S]+|\u{001b}[\s\S]+)/u;
|
|
48
|
+
|
|
23
49
|
const METRO_ERROR_FORMAT =
|
|
24
50
|
/^(?:InternalError Metro has encountered an error:) (.*): (.*) \((\d+):(\d+)\)\n\n([\s\S]+)/u;
|
|
25
51
|
|
|
@@ -166,7 +192,7 @@ export function parseComponentStack(message: string): ComponentStack {
|
|
|
166
192
|
if (!s) {
|
|
167
193
|
return null;
|
|
168
194
|
}
|
|
169
|
-
const match = s.match(/(.*) \(at (.*\.js):([\d]+)\)/);
|
|
195
|
+
const match = s.match(/(.*) \(at (.*\.(?:js|jsx|ts|tsx)):([\d]+)\)/);
|
|
170
196
|
if (!match) {
|
|
171
197
|
return null;
|
|
172
198
|
}
|
|
@@ -241,27 +267,31 @@ export function parseLogBoxException(
|
|
|
241
267
|
};
|
|
242
268
|
}
|
|
243
269
|
|
|
244
|
-
|
|
270
|
+
// Perform a cheap match first before trying to parse the full message, which
|
|
271
|
+
// can get expensive for arbitrary input.
|
|
272
|
+
if (BABEL_CODE_FRAME_MARKER_PATTERN.test(message)) {
|
|
273
|
+
const babelCodeFrameError = message.match(BABEL_CODE_FRAME_ERROR_FORMAT);
|
|
245
274
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
275
|
+
if (babelCodeFrameError) {
|
|
276
|
+
// Codeframe errors are thrown from any use of buildCodeFrameError.
|
|
277
|
+
const [fileName, content, codeFrame] = babelCodeFrameError.slice(1);
|
|
278
|
+
return {
|
|
279
|
+
level: 'syntax',
|
|
280
|
+
stack: [],
|
|
281
|
+
isComponentError: false,
|
|
282
|
+
componentStack: [],
|
|
283
|
+
codeFrame: {
|
|
284
|
+
fileName,
|
|
285
|
+
location: null, // We are not given the location.
|
|
286
|
+
content: codeFrame,
|
|
287
|
+
},
|
|
288
|
+
message: {
|
|
289
|
+
content,
|
|
290
|
+
substitutions: [],
|
|
291
|
+
},
|
|
292
|
+
category: `${fileName}-${1}-${1}`,
|
|
293
|
+
};
|
|
294
|
+
}
|
|
265
295
|
}
|
|
266
296
|
|
|
267
297
|
if (message.match(/^TransformError /)) {
|
|
@@ -10,6 +10,8 @@
|
|
|
10
10
|
|
|
11
11
|
import typeof {enable} from 'promise/setimmediate/rejection-tracking';
|
|
12
12
|
|
|
13
|
+
import LogBox from './LogBox/LogBox';
|
|
14
|
+
|
|
13
15
|
type ExtractOptionsType = <P>(((options?: ?P) => void)) => P;
|
|
14
16
|
|
|
15
17
|
let rejectionTrackingOptions: $Call<ExtractOptionsType, enable> = {
|
|
@@ -34,19 +36,36 @@ let rejectionTrackingOptions: $Call<ExtractOptionsType, enable> = {
|
|
|
34
36
|
? rejection
|
|
35
37
|
: JSON.stringify((rejection: $FlowFixMe));
|
|
36
38
|
}
|
|
39
|
+
// It could although this object is not a standard error, it still has stack information to unwind
|
|
40
|
+
// $FlowFixMe ignore types just check if stack is there
|
|
41
|
+
if (rejection.stack && typeof rejection.stack === 'string') {
|
|
42
|
+
stack = rejection.stack;
|
|
43
|
+
}
|
|
37
44
|
}
|
|
38
45
|
|
|
39
|
-
const warning =
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
46
|
+
const warning = `Possible unhandled promise rejection (id: ${id}):\n${
|
|
47
|
+
message ?? ''
|
|
48
|
+
}`;
|
|
49
|
+
if (__DEV__) {
|
|
50
|
+
LogBox.addLog({
|
|
51
|
+
level: 'warn',
|
|
52
|
+
message: {
|
|
53
|
+
content: warning,
|
|
54
|
+
substitutions: [],
|
|
55
|
+
},
|
|
56
|
+
componentStack: [],
|
|
57
|
+
stack,
|
|
58
|
+
category: 'possible_unhandled_promise_rejection',
|
|
59
|
+
});
|
|
60
|
+
} else {
|
|
61
|
+
console.warn(warning);
|
|
62
|
+
}
|
|
44
63
|
},
|
|
45
64
|
onHandled: id => {
|
|
46
65
|
const warning =
|
|
47
|
-
`Promise
|
|
66
|
+
`Promise rejection handled (id: ${id})\n` +
|
|
48
67
|
'This means you can ignore any previous messages of the form ' +
|
|
49
|
-
`"Possible
|
|
68
|
+
`"Possible unhandled promise rejection (id: ${id}):"`;
|
|
50
69
|
console.warn(warning);
|
|
51
70
|
},
|
|
52
71
|
};
|
|
@@ -10,11 +10,11 @@
|
|
|
10
10
|
-->
|
|
11
11
|
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
12
12
|
<PropertyGroup>
|
|
13
|
-
<ReactNativeWindowsVersion>0.72.
|
|
13
|
+
<ReactNativeWindowsVersion>0.72.33</ReactNativeWindowsVersion>
|
|
14
14
|
<ReactNativeWindowsMajor>0</ReactNativeWindowsMajor>
|
|
15
15
|
<ReactNativeWindowsMinor>72</ReactNativeWindowsMinor>
|
|
16
|
-
<ReactNativeWindowsPatch>
|
|
16
|
+
<ReactNativeWindowsPatch>33</ReactNativeWindowsPatch>
|
|
17
17
|
<ReactNativeWindowsCanary>false</ReactNativeWindowsCanary>
|
|
18
|
-
<ReactNativeWindowsCommitId>
|
|
18
|
+
<ReactNativeWindowsCommitId>64e5b314ccba2fb500617b2617ffb9930cc945ab</ReactNativeWindowsCommitId>
|
|
19
19
|
</PropertyGroup>
|
|
20
20
|
</Project>
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
#include <regex>
|
|
17
17
|
|
|
18
18
|
using std::set;
|
|
19
|
+
using std::string;
|
|
19
20
|
using std::wstring;
|
|
20
21
|
|
|
21
22
|
using winrt::hresult_error;
|
|
@@ -37,22 +38,26 @@ namespace Microsoft::React::Networking {
|
|
|
37
38
|
|
|
38
39
|
#pragma region OriginPolicyHttpFilter
|
|
39
40
|
|
|
40
|
-
#pragma region
|
|
41
|
+
#pragma region CaseInsensitiveComparer
|
|
41
42
|
|
|
42
|
-
bool OriginPolicyHttpFilter::
|
|
43
|
+
bool OriginPolicyHttpFilter::CaseInsensitiveComparer::operator()(const wchar_t *a, const wchar_t *b) const {
|
|
43
44
|
return _wcsicmp(a, b) < 0;
|
|
44
45
|
}
|
|
45
46
|
|
|
46
|
-
|
|
47
|
+
bool OriginPolicyHttpFilter::CaseInsensitiveComparer::operator()(const wstring &a, const wstring &b) const {
|
|
48
|
+
return _wcsicmp(a.c_str(), b.c_str()) < 0;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
#pragma endregion CaseInsensitiveComparer
|
|
47
52
|
|
|
48
53
|
// https://fetch.spec.whatwg.org/#forbidden-method
|
|
49
|
-
/*static*/ set<const wchar_t *, OriginPolicyHttpFilter::
|
|
50
|
-
{L"CONNECT", L"TRACE", L"TRACK"};
|
|
54
|
+
/*static*/ set<const wchar_t *, OriginPolicyHttpFilter::CaseInsensitiveComparer>
|
|
55
|
+
OriginPolicyHttpFilter::s_forbiddenMethods = {L"CONNECT", L"TRACE", L"TRACK"};
|
|
51
56
|
|
|
52
|
-
/*static*/ set<const wchar_t *, OriginPolicyHttpFilter::
|
|
57
|
+
/*static*/ set<const wchar_t *, OriginPolicyHttpFilter::CaseInsensitiveComparer>
|
|
53
58
|
OriginPolicyHttpFilter::s_simpleCorsMethods = {L"GET", L"HEAD", L"POST"};
|
|
54
59
|
|
|
55
|
-
/*static*/ set<const wchar_t *, OriginPolicyHttpFilter::
|
|
60
|
+
/*static*/ set<const wchar_t *, OriginPolicyHttpFilter::CaseInsensitiveComparer>
|
|
56
61
|
OriginPolicyHttpFilter::s_simpleCorsRequestHeaderNames = {
|
|
57
62
|
L"Accept",
|
|
58
63
|
L"Accept-Language",
|
|
@@ -64,11 +69,11 @@ bool OriginPolicyHttpFilter::ConstWcharComparer::operator()(const wchar_t *a, co
|
|
|
64
69
|
L"Viewport-Width",
|
|
65
70
|
L"Width"};
|
|
66
71
|
|
|
67
|
-
/*static*/ set<const wchar_t *, OriginPolicyHttpFilter::
|
|
72
|
+
/*static*/ set<const wchar_t *, OriginPolicyHttpFilter::CaseInsensitiveComparer>
|
|
68
73
|
OriginPolicyHttpFilter::s_simpleCorsResponseHeaderNames =
|
|
69
74
|
{L"Cache-Control", L"Content-Language", L"Content-Type", L"Expires", L"Last-Modified", L"Pragma"};
|
|
70
75
|
|
|
71
|
-
/*static*/ set<const wchar_t *, OriginPolicyHttpFilter::
|
|
76
|
+
/*static*/ set<const wchar_t *, OriginPolicyHttpFilter::CaseInsensitiveComparer>
|
|
72
77
|
OriginPolicyHttpFilter::s_simpleCorsContentTypeValues = {
|
|
73
78
|
L"application/x-www-form-urlencoded",
|
|
74
79
|
L"multipart/form-data",
|
|
@@ -76,7 +81,7 @@ bool OriginPolicyHttpFilter::ConstWcharComparer::operator()(const wchar_t *a, co
|
|
|
76
81
|
|
|
77
82
|
// https://fetch.spec.whatwg.org/#forbidden-header-name
|
|
78
83
|
// Chromium still bans "User-Agent" due to https://crbug.com/571722
|
|
79
|
-
/*static*/ set<const wchar_t *, OriginPolicyHttpFilter::
|
|
84
|
+
/*static*/ set<const wchar_t *, OriginPolicyHttpFilter::CaseInsensitiveComparer>
|
|
80
85
|
OriginPolicyHttpFilter::s_corsForbiddenRequestHeaderNames = {
|
|
81
86
|
L"Accept-Charset",
|
|
82
87
|
L"Accept-Encoding",
|
|
@@ -99,24 +104,15 @@ bool OriginPolicyHttpFilter::ConstWcharComparer::operator()(const wchar_t *a, co
|
|
|
99
104
|
L"Upgrade",
|
|
100
105
|
L"Via"};
|
|
101
106
|
|
|
102
|
-
/*static*/ set<const wchar_t *, OriginPolicyHttpFilter::
|
|
107
|
+
/*static*/ set<const wchar_t *, OriginPolicyHttpFilter::CaseInsensitiveComparer>
|
|
103
108
|
OriginPolicyHttpFilter::s_cookieSettingResponseHeaders = {
|
|
104
109
|
L"Set-Cookie",
|
|
105
110
|
L"Set-Cookie2", // Deprecated by the spec, but probably still used
|
|
106
111
|
};
|
|
107
112
|
|
|
108
|
-
/*static*/ set<const wchar_t *, OriginPolicyHttpFilter::
|
|
113
|
+
/*static*/ set<const wchar_t *, OriginPolicyHttpFilter::CaseInsensitiveComparer>
|
|
109
114
|
OriginPolicyHttpFilter::s_corsForbiddenRequestHeaderNamePrefixes = {L"Proxy-", L"Sec-"};
|
|
110
115
|
|
|
111
|
-
/*static*/ Uri OriginPolicyHttpFilter::s_origin{nullptr};
|
|
112
|
-
|
|
113
|
-
/*static*/ void OriginPolicyHttpFilter::SetStaticOrigin(std::string &&url) {
|
|
114
|
-
if (!url.empty())
|
|
115
|
-
s_origin = Uri{to_hstring(url)};
|
|
116
|
-
else
|
|
117
|
-
s_origin = nullptr;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
116
|
/*static*/ bool OriginPolicyHttpFilter::IsSameOrigin(Uri const &u1, Uri const &u2) noexcept {
|
|
121
117
|
return (u1 && u2) && u1.SchemeName() == u2.SchemeName() && u1.Host() == u2.Host() && u1.Port() == u2.Port();
|
|
122
118
|
}
|
|
@@ -301,7 +297,7 @@ bool OriginPolicyHttpFilter::ConstWcharComparer::operator()(const wchar_t *a, co
|
|
|
301
297
|
}
|
|
302
298
|
|
|
303
299
|
/*static*/ OriginPolicyHttpFilter::AccessControlValues OriginPolicyHttpFilter::ExtractAccessControlValues(
|
|
304
|
-
|
|
300
|
+
IMap<hstring, hstring> const &headers) {
|
|
305
301
|
using std::wregex;
|
|
306
302
|
using std::wsregex_token_iterator;
|
|
307
303
|
|
|
@@ -381,10 +377,14 @@ bool OriginPolicyHttpFilter::ConstWcharComparer::operator()(const wchar_t *a, co
|
|
|
381
377
|
}
|
|
382
378
|
}
|
|
383
379
|
|
|
384
|
-
OriginPolicyHttpFilter::OriginPolicyHttpFilter(IHttpFilter const &innerFilter)
|
|
380
|
+
OriginPolicyHttpFilter::OriginPolicyHttpFilter(string &&origin, IHttpFilter const &innerFilter)
|
|
381
|
+
: m_origin{nullptr}, m_innerFilter{innerFilter} {
|
|
382
|
+
if (!origin.empty())
|
|
383
|
+
m_origin = Uri{to_hstring(origin)};
|
|
384
|
+
}
|
|
385
385
|
|
|
386
|
-
OriginPolicyHttpFilter::OriginPolicyHttpFilter()
|
|
387
|
-
: OriginPolicyHttpFilter(winrt::Windows::Web::Http::Filters::HttpBaseProtocolFilter{}) {}
|
|
386
|
+
OriginPolicyHttpFilter::OriginPolicyHttpFilter(string &&origin)
|
|
387
|
+
: OriginPolicyHttpFilter(std::move(origin), winrt::Windows::Web::Http::Filters::HttpBaseProtocolFilter{}) {}
|
|
388
388
|
|
|
389
389
|
OriginPolicy OriginPolicyHttpFilter::ValidateRequest(HttpRequestMessage const &request) {
|
|
390
390
|
auto effectiveOriginPolicy =
|
|
@@ -394,17 +394,17 @@ OriginPolicy OriginPolicyHttpFilter::ValidateRequest(HttpRequestMessage const &r
|
|
|
394
394
|
return effectiveOriginPolicy;
|
|
395
395
|
|
|
396
396
|
case OriginPolicy::SameOrigin:
|
|
397
|
-
if (!IsSameOrigin(
|
|
397
|
+
if (!IsSameOrigin(m_origin, request.RequestUri()))
|
|
398
398
|
throw hresult_error{E_INVALIDARG, L"SOP (same-origin policy) is enforced"};
|
|
399
399
|
break;
|
|
400
400
|
|
|
401
401
|
case OriginPolicy::SimpleCrossOriginResourceSharing:
|
|
402
402
|
// Check for disallowed mixed content
|
|
403
403
|
if (GetRuntimeOptionBool("Http.BlockMixedContentSimpleCors") &&
|
|
404
|
-
|
|
404
|
+
m_origin.SchemeName() != request.RequestUri().SchemeName())
|
|
405
405
|
throw hresult_error{E_INVALIDARG, L"The origin and request URLs must have the same scheme"};
|
|
406
406
|
|
|
407
|
-
if (IsSameOrigin(
|
|
407
|
+
if (IsSameOrigin(m_origin, request.RequestUri()))
|
|
408
408
|
// Same origin. Therefore, skip Cross-Origin handling.
|
|
409
409
|
effectiveOriginPolicy = OriginPolicy::SameOrigin;
|
|
410
410
|
else if (!IsSimpleCorsRequest(request))
|
|
@@ -420,7 +420,7 @@ OriginPolicy OriginPolicyHttpFilter::ValidateRequest(HttpRequestMessage const &r
|
|
|
420
420
|
// Example: On the Edge browser, an XHR request with the "Host" header set gets rejected as unsafe.
|
|
421
421
|
// https://fetch.spec.whatwg.org/#forbidden-header-name
|
|
422
422
|
|
|
423
|
-
if (
|
|
423
|
+
if (m_origin.SchemeName() != request.RequestUri().SchemeName())
|
|
424
424
|
throw hresult_error{E_INVALIDARG, L"The origin and request URLs must have the same scheme"};
|
|
425
425
|
|
|
426
426
|
if (!AreSafeRequestHeaders(request.Headers()))
|
|
@@ -429,7 +429,7 @@ OriginPolicy OriginPolicyHttpFilter::ValidateRequest(HttpRequestMessage const &r
|
|
|
429
429
|
if (s_forbiddenMethods.find(request.Method().ToString().c_str()) != s_forbiddenMethods.cend())
|
|
430
430
|
throw hresult_error{E_INVALIDARG, L"Request method not allowed in cross-origin resource sharing"};
|
|
431
431
|
|
|
432
|
-
if (IsSameOrigin(
|
|
432
|
+
if (IsSameOrigin(m_origin, request.RequestUri()))
|
|
433
433
|
effectiveOriginPolicy = OriginPolicy::SameOrigin;
|
|
434
434
|
else if (IsSimpleCorsRequest(request))
|
|
435
435
|
effectiveOriginPolicy = OriginPolicy::SimpleCrossOriginResourceSharing;
|
|
@@ -466,7 +466,7 @@ void OriginPolicyHttpFilter::ValidateAllowOrigin(
|
|
|
466
466
|
// 4.10.4 - Mismatched allow origin
|
|
467
467
|
auto taintedOriginProp = props.TryLookup(L"TaintedOrigin");
|
|
468
468
|
auto taintedOrigin = taintedOriginProp && winrt::unbox_value<bool>(taintedOriginProp);
|
|
469
|
-
auto origin = taintedOrigin ? nullptr :
|
|
469
|
+
auto origin = taintedOrigin ? nullptr : m_origin;
|
|
470
470
|
if (allowedOrigin.empty() || !IsSameOrigin(origin, Uri{allowedOrigin})) {
|
|
471
471
|
hstring errorMessage;
|
|
472
472
|
if (allowedOrigin.empty())
|
|
@@ -597,7 +597,7 @@ void OriginPolicyHttpFilter::ValidateResponse(HttpResponseMessage const &respons
|
|
|
597
597
|
bool originAllowed = false;
|
|
598
598
|
for (const auto &header : response.Headers()) {
|
|
599
599
|
if (boost::iequals(header.Key(), L"Access-Control-Allow-Origin")) {
|
|
600
|
-
originAllowed |= L"*" == header.Value() ||
|
|
600
|
+
originAllowed |= L"*" == header.Value() || m_origin == Uri{header.Value()};
|
|
601
601
|
}
|
|
602
602
|
}
|
|
603
603
|
|
|
@@ -685,7 +685,7 @@ ResponseOperation OriginPolicyHttpFilter::SendPreflightAsync(HttpRequestMessage
|
|
|
685
685
|
}
|
|
686
686
|
|
|
687
687
|
preflightRequest.Headers().Insert(L"Access-Control-Request-Headers", headerNames);
|
|
688
|
-
preflightRequest.Headers().Insert(L"Origin", GetOrigin(
|
|
688
|
+
preflightRequest.Headers().Insert(L"Origin", GetOrigin(m_origin));
|
|
689
689
|
preflightRequest.Headers().Insert(L"Sec-Fetch-Mode", L"CORS");
|
|
690
690
|
|
|
691
691
|
co_return {co_await m_innerFilter.SendRequestAsync(preflightRequest)};
|
|
@@ -702,7 +702,7 @@ bool OriginPolicyHttpFilter::OnRedirecting(
|
|
|
702
702
|
// origin=http://a.com. Since the origin matches the URL, the request is authorized at http://a.com, but it actually
|
|
703
703
|
// allows http://b.com to bypass the CORS check at http://a.com since the redirected URL is from http://b.com.
|
|
704
704
|
if (!IsSameOrigin(response.Headers().Location(), request.RequestUri()) &&
|
|
705
|
-
!IsSameOrigin(
|
|
705
|
+
!IsSameOrigin(m_origin, request.RequestUri())) {
|
|
706
706
|
// By masking the origin field in the request header, we make it impossible for the server to set a single value for
|
|
707
707
|
// the access-control-allow-origin header. It means, the only way to support redirect is that server allows access
|
|
708
708
|
// from all sites through wildcard.
|
|
@@ -734,7 +734,7 @@ ResponseOperation OriginPolicyHttpFilter::SendRequestAsync(HttpRequestMessage co
|
|
|
734
734
|
// Allow only HTTP or HTTPS schemes
|
|
735
735
|
if (GetRuntimeOptionBool("Http.StrictScheme") && coRequest.RequestUri().SchemeName() != L"https" &&
|
|
736
736
|
coRequest.RequestUri().SchemeName() != L"http")
|
|
737
|
-
throw hresult_error{E_INVALIDARG, L"Invalid URL scheme: [" +
|
|
737
|
+
throw hresult_error{E_INVALIDARG, L"Invalid URL scheme: [" + m_origin.SchemeName() + L"]"};
|
|
738
738
|
|
|
739
739
|
if (!GetRuntimeOptionBool("Http.OmitCredentials")) {
|
|
740
740
|
coRequest.Properties().Lookup(L"RequestArgs").as<RequestArgs>()->WithCredentials = false;
|
|
@@ -771,7 +771,7 @@ ResponseOperation OriginPolicyHttpFilter::SendRequestAsync(HttpRequestMessage co
|
|
|
771
771
|
|
|
772
772
|
if (originPolicy == OriginPolicy::SimpleCrossOriginResourceSharing ||
|
|
773
773
|
originPolicy == OriginPolicy::CrossOriginResourceSharing) {
|
|
774
|
-
coRequest.Headers().Insert(L"Origin", GetOrigin(
|
|
774
|
+
coRequest.Headers().Insert(L"Origin", GetOrigin(m_origin));
|
|
775
775
|
}
|
|
776
776
|
|
|
777
777
|
auto response = co_await m_innerFilter.SendRequestAsync(coRequest);
|
|
@@ -22,37 +22,35 @@ class OriginPolicyHttpFilter
|
|
|
22
22
|
: public winrt::
|
|
23
23
|
implements<OriginPolicyHttpFilter, winrt::Windows::Web::Http::Filters::IHttpFilter, IRedirectEventSource> {
|
|
24
24
|
public:
|
|
25
|
-
struct
|
|
25
|
+
struct CaseInsensitiveComparer {
|
|
26
26
|
bool operator()(const wchar_t *, const wchar_t *) const;
|
|
27
|
+
bool operator()(const std::wstring &, const std::wstring &) const;
|
|
27
28
|
};
|
|
28
29
|
|
|
29
30
|
private:
|
|
30
|
-
static std::set<const wchar_t *,
|
|
31
|
-
static std::set<const wchar_t *,
|
|
32
|
-
static std::set<const wchar_t *,
|
|
33
|
-
static std::set<const wchar_t *,
|
|
34
|
-
static std::set<const wchar_t *,
|
|
35
|
-
static std::set<const wchar_t *,
|
|
36
|
-
static std::set<const wchar_t *,
|
|
37
|
-
static std::set<const wchar_t *,
|
|
38
|
-
|
|
39
|
-
// NOTE: Assumes static origin through owning client/resource/module/(React) instance's lifetime.
|
|
40
|
-
static winrt::Windows::Foundation::Uri s_origin;
|
|
31
|
+
static std::set<const wchar_t *, CaseInsensitiveComparer> s_forbiddenMethods;
|
|
32
|
+
static std::set<const wchar_t *, CaseInsensitiveComparer> s_simpleCorsMethods;
|
|
33
|
+
static std::set<const wchar_t *, CaseInsensitiveComparer> s_simpleCorsRequestHeaderNames;
|
|
34
|
+
static std::set<const wchar_t *, CaseInsensitiveComparer> s_simpleCorsResponseHeaderNames;
|
|
35
|
+
static std::set<const wchar_t *, CaseInsensitiveComparer> s_simpleCorsContentTypeValues;
|
|
36
|
+
static std::set<const wchar_t *, CaseInsensitiveComparer> s_corsForbiddenRequestHeaderNames;
|
|
37
|
+
static std::set<const wchar_t *, CaseInsensitiveComparer> s_corsForbiddenRequestHeaderNamePrefixes;
|
|
38
|
+
static std::set<const wchar_t *, CaseInsensitiveComparer> s_cookieSettingResponseHeaders;
|
|
41
39
|
|
|
42
40
|
struct AccessControlValues {
|
|
43
41
|
winrt::hstring AllowedOrigin;
|
|
44
42
|
winrt::hstring AllowedCredentials;
|
|
45
|
-
std::set<std::wstring> AllowedHeaders;
|
|
43
|
+
std::set<std::wstring, CaseInsensitiveComparer> AllowedHeaders;
|
|
46
44
|
std::set<std::wstring> AllowedMethods;
|
|
47
|
-
std::set<std::wstring> ExposedHeaders;
|
|
45
|
+
std::set<std::wstring, CaseInsensitiveComparer> ExposedHeaders;
|
|
48
46
|
size_t MaxAge;
|
|
49
47
|
};
|
|
50
48
|
|
|
49
|
+
winrt::Windows::Foundation::Uri m_origin;
|
|
50
|
+
|
|
51
51
|
winrt::Windows::Web::Http::Filters::IHttpFilter m_innerFilter;
|
|
52
52
|
|
|
53
53
|
public:
|
|
54
|
-
static void SetStaticOrigin(std::string &&url);
|
|
55
|
-
|
|
56
54
|
static bool IsSameOrigin(
|
|
57
55
|
winrt::Windows::Foundation::Uri const &u1,
|
|
58
56
|
winrt::Windows::Foundation::Uri const &u2) noexcept;
|
|
@@ -79,9 +77,9 @@ class OriginPolicyHttpFilter
|
|
|
79
77
|
winrt::Windows::Web::Http::HttpResponseMessage const &response,
|
|
80
78
|
bool removeAll);
|
|
81
79
|
|
|
82
|
-
OriginPolicyHttpFilter(winrt::Windows::Web::Http::Filters::IHttpFilter const &innerFilter);
|
|
80
|
+
OriginPolicyHttpFilter(std::string &&origin, winrt::Windows::Web::Http::Filters::IHttpFilter const &innerFilter);
|
|
83
81
|
|
|
84
|
-
OriginPolicyHttpFilter();
|
|
82
|
+
OriginPolicyHttpFilter(std::string &&origin);
|
|
85
83
|
|
|
86
84
|
OriginPolicy ValidateRequest(winrt::Windows::Web::Http::HttpRequestMessage const &request);
|
|
87
85
|
|
|
@@ -641,8 +641,7 @@ void WinRTHttpResource::AddResponseHandler(shared_ptr<IResponseHandler> response
|
|
|
641
641
|
|
|
642
642
|
#pragma region IHttpResource
|
|
643
643
|
|
|
644
|
-
/*static*/ shared_ptr<IHttpResource> IHttpResource::Make(
|
|
645
|
-
winrt::Windows::Foundation::IInspectable const &inspectableProperties) noexcept {
|
|
644
|
+
/*static*/ shared_ptr<IHttpResource> IHttpResource::Make(IInspectable const &inspectableProperties) noexcept {
|
|
646
645
|
using namespace winrt::Microsoft::ReactNative;
|
|
647
646
|
using winrt::Windows::Web::Http::HttpClient;
|
|
648
647
|
|
|
@@ -653,8 +652,7 @@ void WinRTHttpResource::AddResponseHandler(shared_ptr<IResponseHandler> response
|
|
|
653
652
|
client = HttpClient{redirFilter};
|
|
654
653
|
} else {
|
|
655
654
|
auto globalOrigin = GetRuntimeOptionString("Http.GlobalOrigin");
|
|
656
|
-
OriginPolicyHttpFilter
|
|
657
|
-
auto opFilter = winrt::make<OriginPolicyHttpFilter>(redirFilter);
|
|
655
|
+
auto opFilter = winrt::make<OriginPolicyHttpFilter>(std::move(globalOrigin), redirFilter);
|
|
658
656
|
redirFilter.as<RedirectHttpFilter>()->SetRedirectSource(opFilter.as<IRedirectEventSource>());
|
|
659
657
|
|
|
660
658
|
client = HttpClient{opFilter};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-windows",
|
|
3
|
-
"version": "0.72.
|
|
3
|
+
"version": "0.72.33",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -23,29 +23,30 @@
|
|
|
23
23
|
"dependencies": {
|
|
24
24
|
"@babel/runtime": "^7.0.0",
|
|
25
25
|
"@jest/create-cache-key-function": "^29.2.1",
|
|
26
|
-
"@react-native-community/cli": "11.
|
|
27
|
-
"@react-native-community/cli-platform-android": "11.
|
|
28
|
-
"@react-native-community/cli-platform-ios": "11.
|
|
26
|
+
"@react-native-community/cli": "^11.4.1",
|
|
27
|
+
"@react-native-community/cli-platform-android": "^11.4.1",
|
|
28
|
+
"@react-native-community/cli-platform-ios": "^11.4.1",
|
|
29
29
|
"@react-native-windows/cli": "0.72.5",
|
|
30
30
|
"@react-native/assets": "1.0.0",
|
|
31
31
|
"@react-native/assets-registry": "^0.72.0",
|
|
32
|
-
"@react-native/codegen": "^0.72.
|
|
32
|
+
"@react-native/codegen": "^0.72.8",
|
|
33
33
|
"@react-native/gradle-plugin": "^0.72.11",
|
|
34
34
|
"@react-native/js-polyfills": "^0.72.1",
|
|
35
35
|
"@react-native/normalize-colors": "^0.72.0",
|
|
36
36
|
"@react-native/virtualized-lists": "^0.72.8",
|
|
37
37
|
"abort-controller": "^3.0.0",
|
|
38
38
|
"anser": "^1.4.9",
|
|
39
|
+
"ansi-regex": "^5.0.0",
|
|
39
40
|
"base64-js": "^1.1.2",
|
|
40
|
-
"deprecated-react-native-prop-types": "4.
|
|
41
|
+
"deprecated-react-native-prop-types": "^4.2.3",
|
|
41
42
|
"event-target-shim": "^5.0.1",
|
|
42
43
|
"flow-enums-runtime": "^0.0.5",
|
|
43
44
|
"invariant": "^2.2.4",
|
|
44
45
|
"jest-environment-node": "^29.2.1",
|
|
45
46
|
"jsc-android": "^250231.0.0",
|
|
46
47
|
"memoize-one": "^5.0.0",
|
|
47
|
-
"metro-runtime": "0.76.
|
|
48
|
-
"metro-source-map": "0.76.
|
|
48
|
+
"metro-runtime": "^0.76.9",
|
|
49
|
+
"metro-source-map": "^0.76.9",
|
|
49
50
|
"mkdirp": "^0.5.1",
|
|
50
51
|
"nullthrows": "^1.1.1",
|
|
51
52
|
"pretty-format": "^26.5.2",
|
|
@@ -80,7 +81,7 @@
|
|
|
80
81
|
"metro-config": "0.76.4",
|
|
81
82
|
"prettier": "^2.4.1",
|
|
82
83
|
"react": "18.2.0",
|
|
83
|
-
"react-native": "0.72.
|
|
84
|
+
"react-native": "0.72.14",
|
|
84
85
|
"react-native-platform-override": "^1.9.4",
|
|
85
86
|
"react-refresh": "^0.4.0",
|
|
86
87
|
"typescript": "^4.9.5"
|