◐ Shell
clean mode source ↗

util: add fast path for Latin1 decoding · nodejs/node@374eb41

1+

#include "encoding_binding.h"

2+

#include "env-inl.h"

3+

#include "gtest/gtest.h"

4+

#include "node_test_fixture.h"

5+

#include "v8.h"

6+7+

namespace node {

8+

namespace encoding_binding {

9+10+

bool RunDecodeLatin1(Environment* env,

11+

Local<Value> args[],

12+

bool ignore_bom,

13+

bool has_fatal,

14+

Local<Value>* result) {

15+

Isolate* isolate = env->isolate();

16+

TryCatch try_catch(isolate);

17+18+

Local<Boolean> ignoreBOMValue = Boolean::New(isolate, ignore_bom);

19+

Local<Boolean> fatalValue = Boolean::New(isolate, has_fatal);

20+21+

Local<Value> updatedArgs[] = {args[0], ignoreBOMValue, fatalValue};

22+23+

BindingData::DecodeLatin1(FunctionCallbackInfo<Value>(updatedArgs));

24+25+

if (try_catch.HasCaught()) {

26+

return false;

27+

}

28+29+

*result = try_catch.Exception();

30+

return true;

31+

}

32+33+

class EncodingBindingTest : public NodeTestFixture {};

34+35+

TEST_F(EncodingBindingTest, DecodeLatin1_ValidInput) {

36+

Environment* env = CreateEnvironment();

37+

Isolate* isolate = env->isolate();

38+

HandleScope handle_scope(isolate);

39+40+

const uint8_t latin1_data[] = {0xC1, 0xE9, 0xF3};

41+

Local<ArrayBuffer> ab = ArrayBuffer::New(isolate, sizeof(latin1_data));

42+

memcpy(ab->GetBackingStore()->Data(), latin1_data, sizeof(latin1_data));

43+44+

Local<Uint8Array> array = Uint8Array::New(ab, 0, sizeof(latin1_data));

45+

Local<Value> args[] = {array};

46+47+

Local<Value> result;

48+

EXPECT_TRUE(RunDecodeLatin1(env, args, false, false, &result));

49+50+

String::Utf8Value utf8_result(isolate, result);

51+

EXPECT_STREQ(*utf8_result, "Áéó");

52+

}

53+54+

TEST_F(EncodingBindingTest, DecodeLatin1_EmptyInput) {

55+

Environment* env = CreateEnvironment();

56+

Isolate* isolate = env->isolate();

57+

HandleScope handle_scope(isolate);

58+59+

Local<ArrayBuffer> ab = ArrayBuffer::New(isolate, 0);

60+

Local<Uint8Array> array = Uint8Array::New(ab, 0, 0);

61+

Local<Value> args[] = {array};

62+63+

Local<Value> result;

64+

EXPECT_TRUE(RunDecodeLatin1(env, args, false, false, &result));

65+66+

String::Utf8Value utf8_result(isolate, result);

67+

EXPECT_STREQ(*utf8_result, "");

68+

}

69+70+

TEST_F(EncodingBindingTest, DecodeLatin1_InvalidInput) {

71+

Environment* env = CreateEnvironment();

72+

Isolate* isolate = env->isolate();

73+

HandleScope handle_scope(isolate);

74+75+

Local<Value> args[] = {String::NewFromUtf8Literal(isolate, "Invalid input")};

76+77+

Local<Value> result;

78+

EXPECT_FALSE(RunDecodeLatin1(env, args, false, false, &result));

79+

}

80+81+

TEST_F(EncodingBindingTest, DecodeLatin1_IgnoreBOM) {

82+

Environment* env = CreateEnvironment();

83+

Isolate* isolate = env->isolate();

84+

HandleScope handle_scope(isolate);

85+86+

const uint8_t latin1_data[] = {0xFE, 0xFF, 0xC1, 0xE9, 0xF3};

87+

Local<ArrayBuffer> ab = ArrayBuffer::New(isolate, sizeof(latin1_data));

88+

memcpy(ab->GetBackingStore()->Data(), latin1_data, sizeof(latin1_data));

89+90+

Local<Uint8Array> array = Uint8Array::New(ab, 0, sizeof(latin1_data));

91+

Local<Value> args[] = {array};

92+93+

Local<Value> result;

94+

EXPECT_TRUE(RunDecodeLatin1(env, args, true, false, &result));

95+96+

String::Utf8Value utf8_result(isolate, result);

97+

EXPECT_STREQ(*utf8_result, "Áéó");

98+

}

99+100+

TEST_F(EncodingBindingTest, DecodeLatin1_FatalInvalidInput) {

101+

Environment* env = CreateEnvironment();

102+

Isolate* isolate = env->isolate();

103+

HandleScope handle_scope(isolate);

104+105+

const uint8_t invalid_data[] = {0xFF, 0xFF, 0xFF};

106+

Local<ArrayBuffer> ab = ArrayBuffer::New(isolate, sizeof(invalid_data));

107+

memcpy(ab->GetBackingStore()->Data(), invalid_data, sizeof(invalid_data));

108+109+

Local<Uint8Array> array = Uint8Array::New(ab, 0, sizeof(invalid_data));

110+

Local<Value> args[] = {array};

111+112+

Local<Value> result;

113+

EXPECT_FALSE(RunDecodeLatin1(env, args, false, true, &result));

114+

}

115+116+

TEST_F(EncodingBindingTest, DecodeLatin1_IgnoreBOMAndFatal) {

117+

Environment* env = CreateEnvironment();

118+

Isolate* isolate = env->isolate();

119+

HandleScope handle_scope(isolate);

120+121+

const uint8_t latin1_data[] = {0xFE, 0xFF, 0xC1, 0xE9, 0xF3};

122+

Local<ArrayBuffer> ab = ArrayBuffer::New(isolate, sizeof(latin1_data));

123+

memcpy(ab->GetBackingStore()->Data(), latin1_data, sizeof(latin1_data));

124+125+

Local<Uint8Array> array = Uint8Array::New(ab, 0, sizeof(latin1_data));

126+

Local<Value> args[] = {array};

127+128+

Local<Value> result;

129+

EXPECT_TRUE(RunDecodeLatin1(env, args, true, true, &result));

130+131+

String::Utf8Value utf8_result(isolate, result);

132+

EXPECT_STREQ(*utf8_result, "Áéó");

133+

}

134+135+

TEST_F(EncodingBindingTest, DecodeLatin1_BOMPresent) {

136+

Environment* env = CreateEnvironment();

137+

Isolate* isolate = env->isolate();

138+

HandleScope handle_scope(isolate);

139+140+

const uint8_t latin1_data[] = {0xFF, 0xC1, 0xE9, 0xF3};

141+

Local<ArrayBuffer> ab = ArrayBuffer::New(isolate, sizeof(latin1_data));

142+

memcpy(ab->GetBackingStore()->Data(), latin1_data, sizeof(latin1_data));

143+144+

Local<Uint8Array> array = Uint8Array::New(ab, 0, sizeof(latin1_data));

145+

Local<Value> args[] = {array};

146+147+

Local<Value> result;

148+

EXPECT_TRUE(RunDecodeLatin1(env, args, true, false, &result));

149+150+

String::Utf8Value utf8_result(isolate, result);

151+

EXPECT_STREQ(*utf8_result, "Áéó");

152+

}

153+154+

} // namespace encoding_binding

155+

} // namespace node