value.cpp
2.97 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
// Copyright 2004-present Facebook. All Rights Reserved.
#include <string>
#include <gtest/gtest.h>
#include <folly/json.h>
#include <jschelpers/Value.h>
#ifdef WITH_FBJSCEXTENSION
#undef ASSERT
#include <JavaScriptCore/config.h>
#include "OpaqueJSString.h"
#endif
#include <stdexcept>
using namespace facebook::react;
#ifdef ANDROID
#include <android/looper.h>
static void prepare() {
ALooper_prepare(0);
}
#else
static void prepare() {}
#endif
TEST(Value, Undefined) {
prepare();
JSGlobalContextRef ctx = JSC_JSGlobalContextCreateInGroup(false, nullptr, nullptr);
auto v = Value::makeUndefined(ctx);
auto s = String::adopt(ctx, JSC_JSValueToStringCopy(ctx, v, nullptr));
EXPECT_EQ("undefined", s.str());
JSC_JSGlobalContextRelease(ctx);
}
TEST(Value, FromJSON) {
prepare();
JSGlobalContextRef ctx = JSC_JSGlobalContextCreateInGroup(false, nullptr, nullptr);
String s(ctx, "{\"a\": 4}");
Value v(Value::fromJSON(s));
EXPECT_TRUE(v.isObject());
JSC_JSGlobalContextRelease(ctx);
}
TEST(Value, ToJSONString) {
prepare();
JSGlobalContextRef ctx = JSC_JSGlobalContextCreateInGroup(false, nullptr, nullptr);
String s(ctx, "{\"a\": 4}");
Value v(Value::fromJSON(s));
folly::dynamic dyn = folly::parseJson(v.toJSONString());
ASSERT_NE(nullptr, dyn);
EXPECT_TRUE(dyn.isObject());
auto val = dyn.at("a");
ASSERT_NE(nullptr, val);
ASSERT_TRUE(val.isNumber());
EXPECT_EQ(4, val.asInt());
EXPECT_EQ(4.0f, val.asDouble());
JSC_JSGlobalContextRelease(ctx);
}
#ifdef WITH_FBJSCEXTENSION
// Just test that handling invalid data doesn't crash.
TEST(Value, FromBadUtf8) {
prepare();
JSGlobalContextRef ctx = JSC_JSGlobalContextCreateInGroup(false, nullptr, nullptr);
// 110xxxxx 10xxxxxx
auto dyn = folly::dynamic("\xC0");
Value::fromDynamic(ctx, dyn);
dyn = folly::dynamic("\xC0\x00");
Value::fromDynamic(ctx, dyn);
// 1110xxxx 10xxxxxx 10xxxxxx
dyn = "\xE0";
Value::fromDynamic(ctx, dyn);
Value(ctx, Value::fromDynamic(ctx, dyn)).toJSONString();
dyn = "\xE0\x00";
Value::fromDynamic(ctx, dyn);
Value(ctx, Value::fromDynamic(ctx, dyn)).toJSONString();
dyn = "\xE0\x00\x00";
Value::fromDynamic(ctx, dyn);
Value(ctx, Value::fromDynamic(ctx, dyn)).toJSONString();
dyn = "\xE0\xA0\x00";
Value::fromDynamic(ctx, dyn);
// 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
dyn = "\xF0";
Value::fromDynamic(ctx, dyn);
Value(ctx, Value::fromDynamic(ctx, dyn)).toJSONString();
dyn = "\xF0\x00\x00\x00";
Value::fromDynamic(ctx, dyn);
dyn = "\xF0\x80\x80\x00";
Value::fromDynamic(ctx, dyn);
Value(ctx, Value::fromDynamic(ctx, dyn)).toJSONString();
JSC_JSGlobalContextRelease(ctx);
}
// Just test that handling invalid data doesn't crash.
TEST(Value, BadUtf16) {
prepare();
JSGlobalContextRef ctx = JSC_JSGlobalContextCreateInGroup(false, nullptr, nullptr);
UChar buf[] = { 0xDD00, 0xDD00, 0xDD00, 0x1111 };
JSStringRef ref = OpaqueJSString::create(buf, 4).leakRef();
Value v(ctx, ref);
v.toJSONString(0);
JSC_JSGlobalContextRelease(ctx);
}
#endif