OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 1329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1340 " }; \n" | 1340 " }; \n" |
1341 "}; \n"; | 1341 "}; \n"; |
1342 v8::Script::Compile(v8::String::NewFromUtf8(CcTest::isolate(), script)); | 1342 v8::Script::Compile(v8::String::NewFromUtf8(CcTest::isolate(), script)); |
1343 CHECK(try_catch.HasCaught()); | 1343 CHECK(try_catch.HasCaught()); |
1344 v8::String::Utf8Value exception(try_catch.Exception()); | 1344 v8::String::Utf8Value exception(try_catch.Exception()); |
1345 CHECK_EQ("SyntaxError: Octal literals are not allowed in strict mode.", | 1345 CHECK_EQ("SyntaxError: Octal literals are not allowed in strict mode.", |
1346 *exception); | 1346 *exception); |
1347 } | 1347 } |
1348 | 1348 |
1349 | 1349 |
| 1350 namespace { |
| 1351 |
| 1352 const char* use_strict_prefix = "\"use strict\";\n"; |
| 1353 |
| 1354 const char* strict_catch_variable_preparse = "strict_catch_variable"; |
| 1355 const char* strict_catch_variable_parse = |
| 1356 "SyntaxError: Catch variable may not be eval or arguments in strict mode"; |
| 1357 |
| 1358 const char* strict_function_name_preparse = "strict_function_name"; |
| 1359 const char* strict_function_name_parse = |
| 1360 "SyntaxError: Function name may not be eval or arguments in strict mode"; |
| 1361 |
| 1362 const char* strict_lhs_assignment_preparse = "strict_lhs_assignment"; |
| 1363 const char* strict_lhs_assignment_parse = |
| 1364 "SyntaxError: Assignment to eval or arguments is not allowed in strict " |
| 1365 "mode"; |
| 1366 |
| 1367 const char* strict_lhs_postfix_preparse = "strict_lhs_postfix"; |
| 1368 const char* strict_lhs_postfix_parse = |
| 1369 "SyntaxError: Postfix increment/decrement may not have eval or arguments " |
| 1370 "operand in strict mode"; |
| 1371 |
| 1372 const char* strict_lhs_prefix_preparse = "strict_lhs_prefix"; |
| 1373 const char* strict_lhs_prefix_parse = |
| 1374 "SyntaxError: Prefix increment/decrement may not have eval or arguments " |
| 1375 "operand in strict mode"; |
| 1376 |
| 1377 const char* strict_param_name_preparse = "strict_param_name"; |
| 1378 const char* strict_param_name_parse = |
| 1379 "SyntaxError: Parameter name eval or arguments is not allowed in strict " |
| 1380 "mode"; |
| 1381 |
| 1382 const char* strict_var_name_preparse = "strict_var_name"; |
| 1383 const char* strict_var_name_parse = |
| 1384 "SyntaxError: Variable name may not be eval or arguments in strict mode"; |
| 1385 |
| 1386 const char* unexpected_strict_reserved_preparse = "unexpected_strict_reserved"; |
| 1387 const char* unexpected_strict_reserved_parse = |
| 1388 "SyntaxError: Unexpected strict mode reserved word"; |
| 1389 |
| 1390 const char* unexpected_token_identifier_preparse = |
| 1391 "unexpected_token_identifier"; |
| 1392 const char* unexpected_token_identifier_parse = |
| 1393 "SyntaxError: Unexpected identifier"; |
| 1394 |
| 1395 struct ParseErrorTestCase { |
| 1396 const char* source; |
| 1397 int error_location_beg; |
| 1398 int error_location_end; |
| 1399 const char* preparse_error_message; |
| 1400 const char* parse_error_message; |
| 1401 }; |
| 1402 |
| 1403 |
1350 void VerifyPreParseAndParseNoError(v8::Handle<v8::String> source) { | 1404 void VerifyPreParseAndParseNoError(v8::Handle<v8::String> source) { |
1351 v8::ScriptData* preparse = v8::ScriptData::PreCompile(source); | 1405 v8::ScriptData* preparse = v8::ScriptData::PreCompile(source); |
1352 CHECK(!preparse->HasError()); | 1406 CHECK(!preparse->HasError()); |
1353 | 1407 |
1354 v8::TryCatch try_catch; | 1408 v8::TryCatch try_catch; |
1355 v8::Script::Compile(source); | 1409 v8::Script::Compile(source); |
1356 CHECK(!try_catch.HasCaught()); | 1410 CHECK(!try_catch.HasCaught()); |
1357 } | 1411 } |
1358 | 1412 |
1359 | 1413 |
(...skipping 14 matching lines...) Expand all Loading... |
1374 | 1428 |
1375 v8::TryCatch try_catch; | 1429 v8::TryCatch try_catch; |
1376 v8::Script::Compile(source); | 1430 v8::Script::Compile(source); |
1377 CHECK(try_catch.HasCaught()); | 1431 CHECK(try_catch.HasCaught()); |
1378 v8::String::Utf8Value exception(try_catch.Exception()); | 1432 v8::String::Utf8Value exception(try_catch.Exception()); |
1379 CHECK_EQ(parse_error_message, *exception); | 1433 CHECK_EQ(parse_error_message, *exception); |
1380 CHECK_EQ(error_location_beg, try_catch.Message()->GetStartPosition()); | 1434 CHECK_EQ(error_location_beg, try_catch.Message()->GetStartPosition()); |
1381 CHECK_EQ(error_location_end, try_catch.Message()->GetEndPosition()); | 1435 CHECK_EQ(error_location_end, try_catch.Message()->GetEndPosition()); |
1382 } | 1436 } |
1383 | 1437 |
| 1438 } // namespace |
| 1439 |
1384 | 1440 |
1385 TEST(ErrorsEvalAndArguments) { | 1441 TEST(ErrorsEvalAndArguments) { |
1386 // Tests that both preparsing and parsing produce the right kind of errors for | 1442 // Tests that both preparsing and parsing produce the right kind of errors for |
1387 // using "eval" and "arguments" as identifiers. Without the strict mode, it's | 1443 // using "eval" and "arguments" as identifiers. Without the strict mode, it's |
1388 // ok to use "eval" or "arguments" as identifiers. With the strict mode, it | 1444 // ok to use "eval" or "arguments" as identifiers. With the strict mode, it |
1389 // isn't. | 1445 // isn't. |
1390 v8::Isolate* isolate = CcTest::isolate(); | 1446 v8::Isolate* isolate = CcTest::isolate(); |
1391 v8::HandleScope handles(isolate); | 1447 v8::HandleScope handles(isolate); |
1392 v8::Local<v8::Context> context = v8::Context::New(isolate); | 1448 v8::Local<v8::Context> context = v8::Context::New(isolate); |
1393 v8::Context::Scope context_scope(context); | 1449 v8::Context::Scope context_scope(context); |
1394 | 1450 |
1395 const char* use_strict_prefix = "\"use strict\";\n"; | |
1396 int prefix_length = i::StrLength(use_strict_prefix); | 1451 int prefix_length = i::StrLength(use_strict_prefix); |
1397 | 1452 |
1398 const char* strict_var_name_preparse = "strict_var_name"; | 1453 ParseErrorTestCase test_cases[] = { |
1399 const char* strict_var_name_parse = | |
1400 "SyntaxError: Variable name may not be eval or arguments in strict mode"; | |
1401 | |
1402 const char* strict_catch_variable_preparse = "strict_catch_variable"; | |
1403 const char* strict_catch_variable_parse = | |
1404 "SyntaxError: Catch variable may not be eval or arguments in strict mode"; | |
1405 | |
1406 const char* strict_function_name_preparse = "strict_function_name"; | |
1407 const char* strict_function_name_parse = | |
1408 "SyntaxError: Function name may not be eval or arguments in strict mode"; | |
1409 | |
1410 const char* strict_param_name_preparse = "strict_param_name"; | |
1411 const char* strict_param_name_parse = | |
1412 "SyntaxError: Parameter name eval or arguments is not allowed in strict " | |
1413 "mode"; | |
1414 | |
1415 const char* strict_lhs_assignment_preparse = "strict_lhs_assignment"; | |
1416 const char* strict_lhs_assignment_parse = | |
1417 "SyntaxError: Assignment to eval or arguments is not allowed in strict " | |
1418 "mode"; | |
1419 | |
1420 const char* strict_lhs_prefix_preparse = "strict_lhs_prefix"; | |
1421 const char* strict_lhs_prefix_parse = | |
1422 "SyntaxError: Prefix increment/decrement may not have eval or arguments " | |
1423 "operand in strict mode"; | |
1424 | |
1425 const char* strict_lhs_postfix_preparse = "strict_lhs_postfix"; | |
1426 const char* strict_lhs_postfix_parse = | |
1427 "SyntaxError: Postfix increment/decrement may not have eval or arguments " | |
1428 "operand in strict mode"; | |
1429 | |
1430 struct TestCase { | |
1431 const char* source; | |
1432 int error_location_beg; | |
1433 int error_location_end; | |
1434 const char* preparse_error_message; | |
1435 const char* parse_error_message; | |
1436 } test_cases[] = { | |
1437 {"var eval = 42;", 4, 8, strict_var_name_preparse, strict_var_name_parse}, | 1454 {"var eval = 42;", 4, 8, strict_var_name_preparse, strict_var_name_parse}, |
1438 {"var arguments = 42;", 4, 13, strict_var_name_preparse, | 1455 {"var arguments = 42;", 4, 13, strict_var_name_preparse, |
1439 strict_var_name_parse}, | 1456 strict_var_name_parse}, |
1440 {"var foo, eval;", 9, 13, strict_var_name_preparse, strict_var_name_parse}, | 1457 {"var foo, eval;", 9, 13, strict_var_name_preparse, strict_var_name_parse}, |
1441 {"var foo, arguments;", 9, 18, strict_var_name_preparse, | 1458 {"var foo, arguments;", 9, 18, strict_var_name_preparse, |
1442 strict_var_name_parse}, | 1459 strict_var_name_parse}, |
1443 {"try { } catch (eval) { }", 15, 19, strict_catch_variable_preparse, | 1460 {"try { } catch (eval) { }", 15, 19, strict_catch_variable_preparse, |
1444 strict_catch_variable_parse}, | 1461 strict_catch_variable_parse}, |
1445 {"try { } catch (arguments) { }", 15, 24, strict_catch_variable_preparse, | 1462 {"try { } catch (arguments) { }", 15, 24, strict_catch_variable_preparse, |
1446 strict_catch_variable_parse}, | 1463 strict_catch_variable_parse}, |
(...skipping 18 matching lines...) Expand all Loading... |
1465 strict_lhs_prefix_parse}, | 1482 strict_lhs_prefix_parse}, |
1466 {"eval++;", 0, 4, strict_lhs_postfix_preparse, strict_lhs_postfix_parse}, | 1483 {"eval++;", 0, 4, strict_lhs_postfix_preparse, strict_lhs_postfix_parse}, |
1467 {"arguments++;", 0, 9, strict_lhs_postfix_preparse, | 1484 {"arguments++;", 0, 9, strict_lhs_postfix_preparse, |
1468 strict_lhs_postfix_parse}, | 1485 strict_lhs_postfix_parse}, |
1469 {NULL, 0, 0, NULL, NULL} | 1486 {NULL, 0, 0, NULL, NULL} |
1470 }; | 1487 }; |
1471 | 1488 |
1472 for (int i = 0; test_cases[i].source; ++i) { | 1489 for (int i = 0; test_cases[i].source; ++i) { |
1473 v8::Handle<v8::String> source = | 1490 v8::Handle<v8::String> source = |
1474 v8::String::NewFromUtf8(isolate, test_cases[i].source); | 1491 v8::String::NewFromUtf8(isolate, test_cases[i].source); |
1475 | |
1476 VerifyPreParseAndParseNoError(source); | 1492 VerifyPreParseAndParseNoError(source); |
1477 | 1493 |
1478 v8::Handle<v8::String> strict_source = v8::String::Concat( | 1494 v8::Handle<v8::String> strict_source = v8::String::Concat( |
1479 v8::String::NewFromUtf8(isolate, use_strict_prefix), | 1495 v8::String::NewFromUtf8(isolate, use_strict_prefix), |
1480 v8::String::NewFromUtf8(isolate, test_cases[i].source)); | 1496 v8::String::NewFromUtf8(isolate, test_cases[i].source)); |
1481 | |
1482 VerifyPreParseAndParseErrorMessages( | 1497 VerifyPreParseAndParseErrorMessages( |
1483 strict_source, | 1498 strict_source, |
1484 test_cases[i].error_location_beg + prefix_length, | 1499 test_cases[i].error_location_beg + prefix_length, |
| 1500 test_cases[i].error_location_end + prefix_length, |
| 1501 test_cases[i].preparse_error_message, |
| 1502 test_cases[i].parse_error_message); |
| 1503 } |
| 1504 |
| 1505 // Test cases which produce an error also in non-strict mode. |
| 1506 ParseErrorTestCase error_test_cases[] = { |
| 1507 // In this case we expect something completely different, "(", and get |
| 1508 // "eval". It's always "unexpected identifier, whether we are in strict mode |
| 1509 // or not. |
| 1510 {"function foo eval", 13, 17, unexpected_token_identifier_preparse, |
| 1511 unexpected_token_identifier_parse}, |
| 1512 {"\"use strict\"; function foo eval", 27, 31, |
| 1513 unexpected_token_identifier_preparse, unexpected_token_identifier_parse}, |
| 1514 {NULL, 0, 0, NULL, NULL} |
| 1515 }; |
| 1516 |
| 1517 for (int i = 0; error_test_cases[i].source; ++i) { |
| 1518 v8::Handle<v8::String> source = |
| 1519 v8::String::NewFromUtf8(isolate, error_test_cases[i].source); |
| 1520 VerifyPreParseAndParseErrorMessages( |
| 1521 source, |
| 1522 error_test_cases[i].error_location_beg, |
| 1523 error_test_cases[i].error_location_end, |
| 1524 error_test_cases[i].preparse_error_message, |
| 1525 error_test_cases[i].parse_error_message); |
| 1526 } |
| 1527 |
| 1528 // Test cases where only a sub-scope is strict. |
| 1529 ParseErrorTestCase scoped_test_cases[] = { |
| 1530 {"var eval = 1; function foo() { \"use strict\"; var arguments = 2; }", |
| 1531 49, 58, strict_var_name_preparse, strict_var_name_parse}, |
| 1532 {NULL, 0, 0, NULL, NULL} |
| 1533 }; |
| 1534 |
| 1535 for (int i = 0; scoped_test_cases[i].source; ++i) { |
| 1536 v8::Handle<v8::String> source = |
| 1537 v8::String::NewFromUtf8(isolate, scoped_test_cases[i].source); |
| 1538 VerifyPreParseAndParseErrorMessages( |
| 1539 source, |
| 1540 scoped_test_cases[i].error_location_beg, |
| 1541 scoped_test_cases[i].error_location_end, |
| 1542 scoped_test_cases[i].preparse_error_message, |
| 1543 scoped_test_cases[i].parse_error_message); |
| 1544 } |
| 1545 } |
| 1546 |
| 1547 |
| 1548 TEST(ErrorsFutureStrictReservedWords) { |
| 1549 // Tests that both preparsing and parsing produce the right kind of errors for |
| 1550 // using future strict reserved words as identifiers. Without the strict mode, |
| 1551 // it's ok to use future strict reserved words as identifiers. With the strict |
| 1552 // mode, it isn't. |
| 1553 v8::Isolate* isolate = CcTest::isolate(); |
| 1554 v8::HandleScope handles(isolate); |
| 1555 v8::Local<v8::Context> context = v8::Context::New(isolate); |
| 1556 v8::Context::Scope context_scope(context); |
| 1557 |
| 1558 const char* use_strict_prefix = "\"use strict\";\n"; |
| 1559 int prefix_length = i::StrLength(use_strict_prefix); |
| 1560 |
| 1561 ParseErrorTestCase test_cases[] = { |
| 1562 {"var interface = 42;", 4, 13, unexpected_strict_reserved_preparse, |
| 1563 unexpected_strict_reserved_parse}, |
| 1564 {"var foo, interface;", 9, 18, unexpected_strict_reserved_preparse, |
| 1565 unexpected_strict_reserved_parse}, |
| 1566 {"try { } catch (interface) { }", 15, 24, |
| 1567 unexpected_strict_reserved_preparse, unexpected_strict_reserved_parse}, |
| 1568 {"function interface() { }", 9, 18, unexpected_strict_reserved_preparse, |
| 1569 unexpected_strict_reserved_parse}, |
| 1570 {"function foo(interface) { }", 13, 22, unexpected_strict_reserved_preparse, |
| 1571 unexpected_strict_reserved_parse}, |
| 1572 {"function foo(bar, interface) { }", 18, 27, |
| 1573 unexpected_strict_reserved_preparse, unexpected_strict_reserved_parse}, |
| 1574 {"interface = 1;", 0, 9, unexpected_strict_reserved_preparse, |
| 1575 unexpected_strict_reserved_parse}, |
| 1576 {"++interface;", 2, 11, unexpected_strict_reserved_preparse, |
| 1577 unexpected_strict_reserved_parse}, |
| 1578 {"interface++;", 0, 9, unexpected_strict_reserved_preparse, |
| 1579 unexpected_strict_reserved_parse}, |
| 1580 {NULL, 0, 0, NULL, NULL} |
| 1581 }; |
| 1582 |
| 1583 for (int i = 0; test_cases[i].source; ++i) { |
| 1584 v8::Handle<v8::String> source = |
| 1585 v8::String::NewFromUtf8(isolate, test_cases[i].source); |
| 1586 VerifyPreParseAndParseNoError(source); |
| 1587 |
| 1588 v8::Handle<v8::String> strict_source = v8::String::Concat( |
| 1589 v8::String::NewFromUtf8(isolate, use_strict_prefix), |
| 1590 v8::String::NewFromUtf8(isolate, test_cases[i].source)); |
| 1591 VerifyPreParseAndParseErrorMessages( |
| 1592 strict_source, |
| 1593 test_cases[i].error_location_beg + prefix_length, |
1485 test_cases[i].error_location_end + prefix_length, | 1594 test_cases[i].error_location_end + prefix_length, |
1486 test_cases[i].preparse_error_message, | 1595 test_cases[i].preparse_error_message, |
1487 test_cases[i].parse_error_message); | 1596 test_cases[i].parse_error_message); |
1488 } | 1597 } |
| 1598 |
| 1599 // Test cases which produce an error also in non-strict mode. |
| 1600 ParseErrorTestCase error_test_cases[] = { |
| 1601 // In this case we expect something completely different, "(", and get a |
| 1602 // strict reserved word. Note that this differs from the "eval or arguments" |
| 1603 // case; there we just report an unexpected identifier. |
| 1604 {"function foo interface", 13, 22, |
| 1605 unexpected_token_identifier_preparse, |
| 1606 unexpected_token_identifier_parse}, |
| 1607 {"\"use strict\"; function foo interface", 27, 36, |
| 1608 unexpected_strict_reserved_preparse, |
| 1609 unexpected_strict_reserved_parse}, |
| 1610 {NULL, 0, 0, NULL, NULL} |
| 1611 }; |
| 1612 |
| 1613 for (int i = 0; error_test_cases[i].source; ++i) { |
| 1614 v8::Handle<v8::String> source = |
| 1615 v8::String::NewFromUtf8(isolate, error_test_cases[i].source); |
| 1616 VerifyPreParseAndParseErrorMessages( |
| 1617 source, |
| 1618 error_test_cases[i].error_location_beg, |
| 1619 error_test_cases[i].error_location_end, |
| 1620 error_test_cases[i].preparse_error_message, |
| 1621 error_test_cases[i].parse_error_message); |
| 1622 } |
| 1623 |
| 1624 // Test cases where only a sub-scope is strict. |
| 1625 ParseErrorTestCase scoped_test_cases[] = { |
| 1626 {"var interface = 1; function foo() { \"use strict\"; var interface = 2; }", |
| 1627 54, 63, unexpected_strict_reserved_preparse, |
| 1628 unexpected_strict_reserved_parse}, |
| 1629 {NULL, 0, 0, NULL, NULL} |
| 1630 }; |
| 1631 |
| 1632 for (int i = 0; scoped_test_cases[i].source; ++i) { |
| 1633 v8::Handle<v8::String> source = |
| 1634 v8::String::NewFromUtf8(isolate, scoped_test_cases[i].source); |
| 1635 VerifyPreParseAndParseErrorMessages( |
| 1636 source, |
| 1637 scoped_test_cases[i].error_location_beg, |
| 1638 scoped_test_cases[i].error_location_end, |
| 1639 scoped_test_cases[i].preparse_error_message, |
| 1640 scoped_test_cases[i].parse_error_message); |
| 1641 } |
1489 } | 1642 } |
OLD | NEW |