32static QString
escape(
const QString &input)
35 output.reserve(input.size() * 3);
36 const int length = input.size();
37 for (
int i = 0; i < length; ++i) {
38 ushort uc = input.at(i).unicode();
40 if ( (uc > 0x60 && uc < 0x7B)
41 || (uc > 0x3F && uc < 0x5B)
42 || (uc > 0x2C && uc < 0x3A)
46 output.append(QChar(uc));
49 output.append(QLatin1Char(toHexUpper(uc >> 4)));
50 output.append(QLatin1Char(toHexUpper(uc)));
55 output.append(QLatin1Char(toHexUpper(uc >> 12)));
56 output.append(QLatin1Char(toHexUpper(uc >> 8)));
57 output.append(QLatin1Char(toHexUpper(uc >> 4)));
58 output.append(QLatin1Char(toHexUpper(uc)));
67 result.reserve(input.size());
69 const int length = input.size();
71 QChar c = input.at(i++);
72 if ((c == u'%') && (i + 1 < length)) {
73 QChar a = input.at(i);
74 if ((a == u'u') && (i + 4 < length)) {
75 int d3 = fromHex(input.at(i+1).unicode());
76 int d2 = fromHex(input.at(i+2).unicode());
77 int d1 = fromHex(input.at(i+3).unicode());
78 int d0 = fromHex(input.at(i+4).unicode());
79 if ((d3 != -1) && (d2 != -1) && (d1 != -1) && (d0 != -1)) {
80 ushort uc = ushort((d3 << 12) | (d2 << 8) | (d1 << 4) | d0);
81 result.append(QChar(uc));
87 int d1 = fromHex(a.unicode());
88 int d0 = fromHex(input.at(i+1).unicode());
89 if ((d1 != -1) && (d0 != -1)) {
90 c = QChar((d1 << 4) | d0);
113static QString
encode(
const QString &input,
const char *unescapedSet,
bool *ok)
117 const int length = input.size();
120 const QChar c = input.at(i);
122 if ((c.unicode() >=
'a' && c.unicode() <=
'z') ||
123 (c.unicode() >=
'A' && c.unicode() <=
'Z') ||
124 (c.unicode() >=
'0' && c.unicode() <=
'9')) {
127 const char *r = unescapedSet;
129 if (*r == c.unicode()) {
137 uint uc = c.unicode();
138 if ((uc >= 0xDC00) && (uc <= 0xDFFF)) {
142 if (!((uc < 0xD800) || (uc > 0xDBFF))) {
148 const uint uc2 = input.at(i).unicode();
149 if ((uc2 < 0xDC00) || (uc2 > 0xDFFF)) {
153 uc = ((uc - 0xD800) * 0x400) + (uc2 - 0xDC00) + 0x10000;
156 addEscapeSequence(output, (uchar)uc);
159 addEscapeSequence(output, 0xc0 | ((uchar) (uc >> 6)));
162 if (QChar::requiresSurrogates(uc)) {
163 addEscapeSequence(output, 0xf0 | ((uchar) (uc >> 18)));
164 addEscapeSequence(output, 0x80 | (((uchar) (uc >> 12)) & 0x3f));
166 addEscapeSequence(output, 0xe0 | (((uchar) (uc >> 12)) & 0x3f));
168 addEscapeSequence(output, 0x80 | (((uchar) (uc >> 6)) & 0x3f));
170 addEscapeSequence(output, 0x80 | ((uchar) (uc&0x3f)));
191 output.reserve(input.size());
192 const int length = input.size();
194 const QChar percent = QLatin1Char(
'%');
196 const QChar ch = input.at(i);
202 int d1 = fromHex(input.at(i+1).unicode());
203 int d0 = fromHex(input.at(i+2).unicode());
204 if ((d1 == -1) || (d0 == -1))
207 int b = (d1 << 4) | d0;
213 if ((b & 0xe0) == 0xc0) {
217 }
else if ((b & 0xf0) == 0xe0) {
221 }
else if ((b & 0xf8) == 0xf0) {
229 if (i + (3 * need) >= length)
232 for (
int j = 0; j < need; ++j) {
234 if (input.at(i) != percent)
237 d1 = fromHex(input.at(i+1).unicode());
238 d0 = fromHex(input.at(i+2).unicode());
239 if ((d1 == -1) || (d0 == -1))
243 if ((b & 0xC0) != 0x80)
247 uc = (uc << 6) + (b & 0x3f);
253 output.append(QChar(uc));
258 ushort l = ushort(((uc - 0x10000) & 0x3FF) + 0xDC00);
259 ushort h = ushort((((uc - 0x10000) >> 10) & 0x3FF) + 0xD800);
260 output.append(QChar(h));
261 output.append(QChar(l));
272 output.append(QStringView{input}.mid(start, i - start + 1));
274 output.append(QChar(b));
276 output.append(QChar(b));
294void Heap::EvalFunction::init(QV4::ExecutionEngine *engine)
297 Heap::FunctionObject::init(engine, s.engine->id_eval());
298 ScopedFunctionObject f(s,
this);
299 f->defineReadonlyConfigurableProperty(s.engine->id_length(), Value::fromInt32(1));
313ReturnedValue EvalFunction::evalCall(
const Value *,
const Value *argv,
int argc,
bool directCall)
const
316 return Encode::undefined();
318 ExecutionEngine *v4 = engine();
319 const Function *v4Function = v4->currentStackFrame
320 ? v4->currentStackFrame->v4Function
322 const bool isStrict = v4Function && v4Function->isStrict();
326 ScopedContext ctx(scope, evalContext(v4, directCall));
328 String *scode = argv[0].stringValue();
330 return argv[0].asReturnedValue();
332 const QString code = scode->toQString();
333 bool inheritContext = !isStrict;
335 Script script(ctx, QV4::Compiler::ContextType::Eval, code, QStringLiteral(
"eval code"));
336 script.setStrictMode(directCall && isStrict);
337 script.setInheritContext(inheritContext);
339 if (v4->hasException)
340 return Encode::undefined();
342 Function *function = script.function();
344 return Encode::undefined();
345 function->kind = Function::Eval;
347 ScopedValue thisObject(scope, directCall
348 ? scope.engine->currentStackFrame->thisObject()
349 : scope.engine->globalObject->asReturnedValue());
350 if (function->isStrict() || isStrict) {
351 ScopedFunctionObject e(scope, FunctionObject::createScriptFunction(ctx, function));
352 return checkedResult(v4, e->call(thisObject,
nullptr, 0));
355 return checkedResult(v4, function->call(thisObject,
nullptr, 0, ctx));
383ReturnedValue
GlobalFunctions::method_parseInt(
const FunctionObject *b,
const Value *,
const Value *argv,
int argc)
386 ScopedValue inputString(scope, argc ? argv[0] : Value::undefinedValue());
387 ScopedValue radix(scope, argc > 1 ? argv[1] : Value::undefinedValue());
388 int R = radix
->isUndefined() ? 0 : radix
->toInt32();
391 QString trimmed = inputString->toQString().trimmed();
394 const QChar *pos = trimmed.constData();
395 const QChar *end = pos + trimmed.size();
399 if (*pos == QLatin1Char(
'-'))
401 if (*pos == QLatin1Char(
'-') || *pos == QLatin1Char(
'+'))
404 bool stripPrefix =
true;
407 RETURN_RESULT(Encode(std::numeric_limits<
double>::quiet_NaN()));
415 && (pos[0] == QLatin1Char(
'0'))
416 && (pos[1] == QLatin1Char(
'x') || pos[1] == QLatin1Char(
'X'))) {
424 RETURN_RESULT(Encode(std::numeric_limits<
double>::quiet_NaN()));
425 bool overflow =
false;
426 qint64 v_overflow = 0;
427 unsigned overflow_digit_count = 0;
428 int d = toInt(*pos++, R);
430 RETURN_RESULT(Encode(std::numeric_limits<
double>::quiet_NaN()));
433 d = toInt(*pos++, R);
437 if (overflow_digit_count == 0) {
441 ++overflow_digit_count;
444 qint64 vNew = v * R + d;
455 double result = (
double) v_overflow * pow(
static_cast<
double>(R),
static_cast<
double>(overflow_digit_count));
464ReturnedValue
GlobalFunctions::method_parseFloat(
const FunctionObject *b,
const Value *,
const Value *argv,
int argc)
468 ScopedString inputString(scope, argc ? argv[0] : Value::undefinedValue(), ScopedString::Convert);
471 QString trimmed = inputString->toQString().trimmed();
474 if (trimmed.startsWith(QLatin1String(
"Infinity"))
475 || trimmed.startsWith(QLatin1String(
"+Infinity")))
477 if (trimmed.startsWith(QLatin1String(
"-Infinity")))
479 QByteArray ba = trimmed.toLatin1();
481 const char *begin = ba.constData();
482 const char *end =
nullptr;
483 double d = qstrtod(begin, &end, &ok);
484 if (end - begin == 0)
485 RETURN_RESULT(Encode(std::numeric_limits<
double>::quiet_NaN()));
519ReturnedValue
GlobalFunctions::method_decodeURI(
const FunctionObject *b,
const Value *,
const Value *argv,
int argc)
524 ExecutionEngine *v4 = b->engine();
525 QString uriString = argv[0].toQString();
527 QString out = decode(uriString, DecodeNonReserved, &ok);
530 ScopedString s(scope, scope.engine->newString(QStringLiteral(
"malformed URI sequence")));
538ReturnedValue
GlobalFunctions::method_decodeURIComponent(
const FunctionObject *b,
const Value *,
const Value *argv,
int argc)
543 ExecutionEngine *v4 = b->engine();
544 QString uriString = argv[0].toQString();
546 QString out = decode(uriString, DecodeAll, &ok);
549 ScopedString s(scope, scope.engine->newString(QStringLiteral(
"malformed URI sequence")));
557ReturnedValue
GlobalFunctions::method_encodeURI(
const FunctionObject *b,
const Value *,
const Value *argv,
int argc)
562 ExecutionEngine *v4 = b->engine();
563 QString uriString = argv[0].toQString();
565 QString out = encode(uriString, uriUnescapedReserved, &ok);
568 ScopedString s(scope, scope.engine->newString(QStringLiteral(
"malformed URI sequence")));
576ReturnedValue
GlobalFunctions::method_encodeURIComponent(
const FunctionObject *b,
const Value *,
const Value *argv,
int argc)
581 ExecutionEngine *v4 = b->engine();
582 QString uriString = argv[0].toQString();
584 QString out = encode(uriString, uriUnescaped, &ok);
587 ScopedString s(scope, scope.engine->newString(QStringLiteral(
"malformed URI sequence")));