Chromium Code Reviews| Index: src/builtins.cc |
| diff --git a/src/builtins.cc b/src/builtins.cc |
| index 20d00bb7e384f0cab49e766717f55d49c313d437..c4e3c358696bb3801349f54bd4fe6b9ae0e17247 100644 |
| --- a/src/builtins.cc |
| +++ b/src/builtins.cc |
| @@ -9,6 +9,7 @@ |
| #include "src/api.h" |
| #include "src/base/once.h" |
| #include "src/bootstrapper.h" |
| +#include "src/char-predicates-inl.h" |
| #include "src/code-factory.h" |
| #include "src/code-stub-assembler.h" |
| #include "src/dateparser-inl.h" |
| @@ -2106,6 +2107,147 @@ BUILTIN(ObjectSeal) { |
| return *object; |
| } |
| +// anonymous namespace for URIEncode helper functions |
| +namespace { |
| + |
| +bool IsUnescapePredicateInUriComponent(uc16 c) { |
| + if (IsAlphaNumeric(c)) { |
| + return true; |
| + } |
| + |
| + switch (c) { |
| + case '!': |
| + case '\'': |
| + case '(': |
| + case ')': |
| + case '*': |
| + case '-': |
| + case '.': |
| + case '_': |
| + case '~': |
| + return true; |
| + default: |
| + return false; |
| + } |
| +} |
| + |
| +bool IsUriSeparator(uc16 c) { |
| + switch (c) { |
| + case '#': |
| + case ':': |
| + case ';': |
| + case '/': |
| + case '?': |
| + case '$': |
| + case '&': |
| + case '+': |
| + case ',': |
| + case '@': |
| + case '=': |
| + return true; |
| + default: |
| + return false; |
| + } |
| +} |
| + |
| +void AddHexEncodedToBuffer(uint8_t octet, List<uint8_t>* buffer) { |
| + buffer->Add('%'); |
| + buffer->Add(HexCharOfValue(octet >> 4)); |
| + buffer->Add(HexCharOfValue(octet & 0x0F)); |
| +} |
| + |
| +void EncodeSingle(uc16 c, List<uint8_t>* buffer) { |
| + uint8_t x = (c >> 12) & 0xF; |
| + uint8_t y = (c >> 6) & 63; |
| + uint8_t z = c & 63; |
| + if (c <= 0x007F) { |
| + AddHexEncodedToBuffer(c, buffer); |
| + } else if (c <= 0x07FF) { |
| + AddHexEncodedToBuffer(y + 192, buffer); |
| + AddHexEncodedToBuffer(z + 128, buffer); |
| + } else { |
| + AddHexEncodedToBuffer(x + 224, buffer); |
| + AddHexEncodedToBuffer(y + 128, buffer); |
| + AddHexEncodedToBuffer(z + 128, buffer); |
| + } |
| +} |
| + |
| +void EncodePair(uc16 cc1, uc16 cc2, List<uint8_t>* buffer) { |
| + uint8_t u = ((cc1 >> 6) & 0xF) + 1; |
| + uint8_t w = (cc1 >> 2) & 0xF; |
| + uint8_t x = cc1 & 3; |
| + uint8_t y = (cc2 >> 6) & 0xF; |
| + uint8_t z = cc2 & 63; |
| + AddHexEncodedToBuffer((u >> 2) + 240, buffer); |
| + AddHexEncodedToBuffer((((u & 3) << 4) | w) + 128, buffer); |
| + AddHexEncodedToBuffer(((x << 4) | y) + 128, buffer); |
| + AddHexEncodedToBuffer(z + 128, buffer); |
| +} |
| + |
| +Object* EncodeUri(Isolate* isolate, Handle<String> uri, bool is_uri) { |
| + uri = String::Flatten(uri); |
| + int uri_length = uri->length(); |
| + List<uint8_t> buffer(uri_length); |
| + |
| + { |
| + DisallowHeapAllocation no_gc; |
| + String::FlatContent uri_content = uri->GetFlatContent(); |
| + |
| + for (int k = 0; k < uri_length; k++) { |
| + uc16 cc1 = uri_content.Get(k); |
| + if (unibrow::Utf16::IsLeadSurrogate(cc1)) { |
| + k++; |
| + if (k < uri_length) { |
| + uc16 cc2 = uri->Get(k); |
| + if (unibrow::Utf16::IsTrailSurrogate(cc2)) { |
| + EncodePair(cc1, cc2, &buffer); |
| + continue; |
| + } |
| + } |
| + } else if (!unibrow::Utf16::IsTrailSurrogate(cc1)) { |
| + if (IsUnescapePredicateInUriComponent(cc1) || |
| + (is_uri && IsUriSeparator(cc1))) { |
| + buffer.Add(cc1); |
| + } else { |
| + EncodeSingle(cc1, &buffer); |
| + } |
| + continue; |
| + } |
| + |
| + AllowHeapAllocation allocate_error_and_return; |
| + THROW_NEW_ERROR_RETURN_FAILURE(isolate, NewURIError()); |
| + } |
| + } |
| + |
| + Handle<String> result; |
| + ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
| + isolate, result, |
| + isolate->factory()->NewStringFromOneByte(buffer.ToConstVector())); |
| + return *result; |
| +} |
| + |
| +} // namespace |
| + |
| +// ES6 section 18.2.6.4 encodeURI (uri) |
| +BUILTIN(GlobalEncodeURI) { |
| + HandleScope scope(isolate); |
| + Handle<String> uri; |
| + ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
| + isolate, uri, Object::ToString(isolate, args.atOrUndefined(isolate, 1))); |
| + |
| + return EncodeUri(isolate, uri, true); |
|
Yang
2016/05/17 05:15:38
builtins.cc is already bloated from all sorts of t
Franzi
2016/05/17 10:25:31
Moved into src/uri.h
|
| +} |
| + |
| +// ES6 section 18.2.6.5 encodeURIComponenet (uriComponent) |
| +BUILTIN(GlobalEncodeURIComponent) { |
| + HandleScope scope(isolate); |
| + Handle<String> uriComponent; |
| + ASSIGN_RETURN_FAILURE_ON_EXCEPTION( |
| + isolate, uriComponent, |
| + Object::ToString(isolate, args.atOrUndefined(isolate, 1))); |
| + |
| + return EncodeUri(isolate, uriComponent, false); |
| +} |
| namespace { |