test_securecontext_extended_attribute.py (24178B)
1 import WebIDL 2 3 4 def WebIDLTest(parser, harness): 5 parser.parse( 6 """ 7 [SecureContext] 8 interface TestSecureContextOnInterface { 9 const octet TEST_CONSTANT = 0; 10 readonly attribute byte testAttribute; 11 undefined testMethod(byte foo); 12 }; 13 partial interface TestSecureContextOnInterface { 14 const octet TEST_CONSTANT_2 = 0; 15 readonly attribute byte testAttribute2; 16 undefined testMethod2(byte foo); 17 }; 18 """ 19 ) 20 results = parser.finish() 21 harness.check( 22 len(results[0].members), 23 6, 24 "TestSecureContextOnInterface should have six members", 25 ) 26 harness.ok( 27 results[0].getExtendedAttribute("SecureContext"), 28 "Interface should have [SecureContext] extended attribute", 29 ) 30 harness.ok( 31 results[0].members[0].getExtendedAttribute("SecureContext"), 32 "[SecureContext] should propagate from interface to constant members", 33 ) 34 harness.ok( 35 results[0].members[1].getExtendedAttribute("SecureContext"), 36 "[SecureContext] should propagate from interface to attribute members", 37 ) 38 harness.ok( 39 results[0].members[2].getExtendedAttribute("SecureContext"), 40 "[SecureContext] should propagate from interface to method members", 41 ) 42 harness.ok( 43 results[0].members[3].getExtendedAttribute("SecureContext"), 44 ( 45 "[SecureContext] should propagate from interface to " 46 "constant members from partial interface" 47 ), 48 ) 49 harness.ok( 50 results[0].members[4].getExtendedAttribute("SecureContext"), 51 ( 52 "[SecureContext] should propagate from interface to " 53 "attribute members from partial interface" 54 ), 55 ) 56 harness.ok( 57 results[0].members[5].getExtendedAttribute("SecureContext"), 58 "[SecureContext] should propagate from interface to method members from partial interface", 59 ) 60 61 # Same thing, but with the partial interface specified first: 62 parser = parser.reset() 63 parser.parse( 64 """ 65 partial interface TestSecureContextOnInterfaceAfterPartialInterface { 66 const octet TEST_CONSTANT_2 = 0; 67 readonly attribute byte testAttribute2; 68 undefined testMethod2(byte foo); 69 }; 70 [SecureContext] 71 interface TestSecureContextOnInterfaceAfterPartialInterface { 72 const octet TEST_CONSTANT = 0; 73 readonly attribute byte testAttribute; 74 undefined testMethod(byte foo); 75 }; 76 """ 77 ) 78 results = parser.finish() 79 harness.check( 80 len(results[1].members), 81 6, 82 "TestSecureContextOnInterfaceAfterPartialInterface should have six members", 83 ) 84 harness.ok( 85 results[1].getExtendedAttribute("SecureContext"), 86 "Interface should have [SecureContext] extended attribute", 87 ) 88 harness.ok( 89 results[1].members[0].getExtendedAttribute("SecureContext"), 90 "[SecureContext] should propagate from interface to constant members", 91 ) 92 harness.ok( 93 results[1].members[1].getExtendedAttribute("SecureContext"), 94 "[SecureContext] should propagate from interface to attribute members", 95 ) 96 harness.ok( 97 results[1].members[2].getExtendedAttribute("SecureContext"), 98 "[SecureContext] should propagate from interface to method members", 99 ) 100 harness.ok( 101 results[1].members[3].getExtendedAttribute("SecureContext"), 102 ( 103 "[SecureContext] should propagate from interface to constant members from " 104 "partial interface" 105 ), 106 ) 107 harness.ok( 108 results[1].members[4].getExtendedAttribute("SecureContext"), 109 ( 110 "[SecureContext] should propagate from interface to attribute members from " 111 "partial interface" 112 ), 113 ) 114 harness.ok( 115 results[1].members[5].getExtendedAttribute("SecureContext"), 116 ( 117 "[SecureContext] should propagate from interface to method members from partial " 118 "interface" 119 ), 120 ) 121 122 parser = parser.reset() 123 parser.parse( 124 """ 125 interface TestSecureContextOnPartialInterface { 126 const octet TEST_CONSTANT = 0; 127 readonly attribute byte testAttribute; 128 undefined testMethod(byte foo); 129 }; 130 [SecureContext] 131 partial interface TestSecureContextOnPartialInterface { 132 const octet TEST_CONSTANT_2 = 0; 133 readonly attribute byte testAttribute2; 134 undefined testMethod2(byte foo); 135 }; 136 """ 137 ) 138 results = parser.finish() 139 harness.check( 140 len(results[0].members), 141 6, 142 "TestSecureContextOnPartialInterface should have six members", 143 ) 144 harness.ok( 145 results[0].getExtendedAttribute("SecureContext") is None, 146 "[SecureContext] should not propagate from a partial interface to the interface", 147 ) 148 harness.ok( 149 results[0].members[0].getExtendedAttribute("SecureContext") is None, 150 ( 151 "[SecureContext] should not propagate from a partial interface to the interface's " 152 "constant members" 153 ), 154 ) 155 harness.ok( 156 results[0].members[1].getExtendedAttribute("SecureContext") is None, 157 ( 158 "[SecureContext] should not propagate from a partial interface to the interface's " 159 "attribute members" 160 ), 161 ) 162 harness.ok( 163 results[0].members[2].getExtendedAttribute("SecureContext") is None, 164 ( 165 "[SecureContext] should not propagate from a partial interface to the interface's " 166 "method members" 167 ), 168 ) 169 harness.ok( 170 results[0].members[3].getExtendedAttribute("SecureContext"), 171 "Constant members from [SecureContext] partial interface should be [SecureContext]", 172 ) 173 harness.ok( 174 results[0].members[4].getExtendedAttribute("SecureContext"), 175 "Attribute members from [SecureContext] partial interface should be [SecureContext]", 176 ) 177 harness.ok( 178 results[0].members[5].getExtendedAttribute("SecureContext"), 179 "Method members from [SecureContext] partial interface should be [SecureContext]", 180 ) 181 182 parser = parser.reset() 183 parser.parse( 184 """ 185 interface TestSecureContextOnInterfaceMembers { 186 const octet TEST_NON_SECURE_CONSTANT_1 = 0; 187 [SecureContext] 188 const octet TEST_SECURE_CONSTANT = 1; 189 const octet TEST_NON_SECURE_CONSTANT_2 = 2; 190 readonly attribute byte testNonSecureAttribute1; 191 [SecureContext] 192 readonly attribute byte testSecureAttribute; 193 readonly attribute byte testNonSecureAttribute2; 194 undefined testNonSecureMethod1(byte foo); 195 [SecureContext] 196 undefined testSecureMethod(byte foo); 197 undefined testNonSecureMethod2(byte foo); 198 }; 199 """ 200 ) 201 results = parser.finish() 202 harness.check( 203 len(results[0].members), 204 9, 205 "TestSecureContextOnInterfaceMembers should have nine members", 206 ) 207 harness.ok( 208 results[0].getExtendedAttribute("SecureContext") is None, 209 "[SecureContext] on members should not propagate up to the interface", 210 ) 211 harness.ok( 212 results[0].members[0].getExtendedAttribute("SecureContext") is None, 213 "Constant should not have [SecureContext] extended attribute", 214 ) 215 harness.ok( 216 results[0].members[1].getExtendedAttribute("SecureContext"), 217 "Constant should have [SecureContext] extended attribute", 218 ) 219 harness.ok( 220 results[0].members[2].getExtendedAttribute("SecureContext") is None, 221 "Constant should not have [SecureContext] extended attribute", 222 ) 223 harness.ok( 224 results[0].members[3].getExtendedAttribute("SecureContext") is None, 225 "Attribute should not have [SecureContext] extended attribute", 226 ) 227 harness.ok( 228 results[0].members[4].getExtendedAttribute("SecureContext"), 229 "Attribute should have [SecureContext] extended attribute", 230 ) 231 harness.ok( 232 results[0].members[5].getExtendedAttribute("SecureContext") is None, 233 "Attribute should not have [SecureContext] extended attribute", 234 ) 235 harness.ok( 236 results[0].members[6].getExtendedAttribute("SecureContext") is None, 237 "Method should not have [SecureContext] extended attribute", 238 ) 239 harness.ok( 240 results[0].members[7].getExtendedAttribute("SecureContext"), 241 "Method should have [SecureContext] extended attribute", 242 ) 243 harness.ok( 244 results[0].members[8].getExtendedAttribute("SecureContext") is None, 245 "Method should not have [SecureContext] extended attribute", 246 ) 247 248 parser = parser.reset() 249 parser.parse( 250 """ 251 interface TestSecureContextOnPartialInterfaceMembers { 252 }; 253 partial interface TestSecureContextOnPartialInterfaceMembers { 254 const octet TEST_NON_SECURE_CONSTANT_1 = 0; 255 [SecureContext] 256 const octet TEST_SECURE_CONSTANT = 1; 257 const octet TEST_NON_SECURE_CONSTANT_2 = 2; 258 readonly attribute byte testNonSecureAttribute1; 259 [SecureContext] 260 readonly attribute byte testSecureAttribute; 261 readonly attribute byte testNonSecureAttribute2; 262 undefined testNonSecureMethod1(byte foo); 263 [SecureContext] 264 undefined testSecureMethod(byte foo); 265 undefined testNonSecureMethod2(byte foo); 266 }; 267 """ 268 ) 269 results = parser.finish() 270 harness.check( 271 len(results[0].members), 272 9, 273 "TestSecureContextOnPartialInterfaceMembers should have nine members", 274 ) 275 harness.ok( 276 results[0].members[0].getExtendedAttribute("SecureContext") is None, 277 "Constant from partial interface should not have [SecureContext] extended attribute", 278 ) 279 harness.ok( 280 results[0].members[1].getExtendedAttribute("SecureContext"), 281 "Constant from partial interface should have [SecureContext] extended attribute", 282 ) 283 harness.ok( 284 results[0].members[2].getExtendedAttribute("SecureContext") is None, 285 "Constant from partial interface should not have [SecureContext] extended attribute", 286 ) 287 harness.ok( 288 results[0].members[3].getExtendedAttribute("SecureContext") is None, 289 "Attribute from partial interface should not have [SecureContext] extended attribute", 290 ) 291 harness.ok( 292 results[0].members[4].getExtendedAttribute("SecureContext"), 293 "Attribute from partial interface should have [SecureContext] extended attribute", 294 ) 295 harness.ok( 296 results[0].members[5].getExtendedAttribute("SecureContext") is None, 297 "Attribute from partial interface should not have [SecureContext] extended attribute", 298 ) 299 harness.ok( 300 results[0].members[6].getExtendedAttribute("SecureContext") is None, 301 "Method from partial interface should not have [SecureContext] extended attribute", 302 ) 303 harness.ok( 304 results[0].members[7].getExtendedAttribute("SecureContext"), 305 "Method from partial interface should have [SecureContext] extended attribute", 306 ) 307 harness.ok( 308 results[0].members[8].getExtendedAttribute("SecureContext") is None, 309 "Method from partial interface should not have [SecureContext] extended attribute", 310 ) 311 312 parser = parser.reset() 313 threw = False 314 try: 315 parser.parse( 316 """ 317 [SecureContext=something] 318 interface TestSecureContextTakesNoValue1 { 319 const octet TEST_SECURE_CONSTANT = 0; 320 }; 321 """ 322 ) 323 results = parser.finish() 324 except WebIDL.WebIDLError: 325 threw = True 326 harness.ok(threw, "[SecureContext] must take no arguments (testing on interface)") 327 328 parser = parser.reset() 329 threw = False 330 try: 331 parser.parse( 332 """ 333 interface TestSecureContextForOverloads1 { 334 [SecureContext] 335 undefined testSecureMethod(byte foo); 336 }; 337 partial interface TestSecureContextForOverloads1 { 338 undefined testSecureMethod(byte foo, byte bar); 339 }; 340 """ 341 ) 342 results = parser.finish() 343 except WebIDL.WebIDLError: 344 threw = True 345 harness.ok( 346 threw, 347 ( 348 "If [SecureContext] appears on an overloaded operation, then it MUST appear on all " 349 "overloads" 350 ), 351 ) 352 353 parser = parser.reset() 354 threw = False 355 try: 356 parser.parse( 357 """ 358 interface TestSecureContextForOverloads2 { 359 [SecureContext] 360 undefined testSecureMethod(byte foo); 361 }; 362 partial interface TestSecureContextForOverloads2 { 363 [SecureContext] 364 undefined testSecureMethod(byte foo, byte bar); 365 }; 366 """ 367 ) 368 results = parser.finish() 369 except WebIDL.WebIDLError: 370 threw = True 371 harness.ok( 372 not threw, 373 "[SecureContext] can appear on an overloaded operation if it appears on all overloads", 374 ) 375 376 parser = parser.reset() 377 threw = False 378 try: 379 parser.parse( 380 """ 381 [SecureContext] 382 interface TestSecureContextOnInterfaceAndMember { 383 [SecureContext] 384 undefined testSecureMethod(byte foo); 385 }; 386 """ 387 ) 388 results = parser.finish() 389 except WebIDL.WebIDLError: 390 threw = True 391 harness.ok( 392 threw, "[SecureContext] must not appear on an interface and interface member" 393 ) 394 395 parser = parser.reset() 396 threw = False 397 try: 398 parser.parse( 399 """ 400 interface TestSecureContextOnPartialInterfaceAndMember { 401 }; 402 [SecureContext] 403 partial interface TestSecureContextOnPartialInterfaceAndMember { 404 [SecureContext] 405 undefined testSecureMethod(byte foo); 406 }; 407 """ 408 ) 409 results = parser.finish() 410 except WebIDL.WebIDLError: 411 threw = True 412 harness.ok( 413 threw, 414 ( 415 "[SecureContext] must not appear on a partial interface and one of the partial " 416 "interface's member's" 417 ), 418 ) 419 420 parser = parser.reset() 421 threw = False 422 try: 423 parser.parse( 424 """ 425 [SecureContext] 426 interface TestSecureContextOnInterfaceAndPartialInterfaceMember { 427 }; 428 partial interface TestSecureContextOnInterfaceAndPartialInterfaceMember { 429 [SecureContext] 430 undefined testSecureMethod(byte foo); 431 }; 432 """ 433 ) 434 results = parser.finish() 435 except WebIDL.WebIDLError: 436 threw = True 437 harness.ok( 438 threw, 439 ( 440 "[SecureContext] must not appear on an interface and one of its partial interface's " 441 "member's" 442 ), 443 ) 444 445 parser = parser.reset() 446 threw = False 447 try: 448 parser.parse( 449 """ 450 [SecureContext] 451 interface TestSecureContextOnInheritedInterface { 452 }; 453 interface TestSecureContextNotOnInheritingInterface : TestSecureContextOnInheritedInterface { 454 undefined testSecureMethod(byte foo); 455 }; 456 """ 457 ) 458 results = parser.finish() 459 except WebIDL.WebIDLError: 460 threw = True 461 harness.ok( 462 threw, 463 ( 464 "[SecureContext] must appear on interfaces that inherit from another [SecureContext] " 465 "interface" 466 ), 467 ) 468 469 # Test namespace 470 parser = parser.reset() 471 parser.parse( 472 """ 473 [SecureContext] 474 namespace TestSecureContextOnNamespace { 475 const octet TEST_CONSTANT = 0; 476 readonly attribute byte testAttribute; 477 undefined testMethod(byte foo); 478 }; 479 partial namespace TestSecureContextOnNamespace { 480 const octet TEST_CONSTANT_2 = 0; 481 readonly attribute byte testAttribute2; 482 undefined testMethod2(byte foo); 483 }; 484 """ 485 ) 486 results = parser.finish() 487 harness.check( 488 len(results[0].members), 489 6, 490 "TestSecureContextOnNamespace should have six members", 491 ) 492 harness.ok( 493 results[0].getExtendedAttribute("SecureContext"), 494 "Namespace should have [SecureContext] extended attribute", 495 ) 496 harness.ok( 497 results[0].members[0].getExtendedAttribute("SecureContext"), 498 "[SecureContext] should propagate from namespace to constant members", 499 ) 500 harness.ok( 501 results[0].members[1].getExtendedAttribute("SecureContext"), 502 "[SecureContext] should propagate from namespace to attribute members", 503 ) 504 harness.ok( 505 results[0].members[2].getExtendedAttribute("SecureContext"), 506 "[SecureContext] should propagate from namespace to method members", 507 ) 508 harness.ok( 509 results[0].members[3].getExtendedAttribute("SecureContext"), 510 ( 511 "[SecureContext] should propagate from namespace to " 512 "constant members from partial namespace" 513 ), 514 ) 515 harness.ok( 516 results[0].members[4].getExtendedAttribute("SecureContext"), 517 ( 518 "[SecureContext] should propagate from namespace to " 519 "attribute members from partial namespace" 520 ), 521 ) 522 harness.ok( 523 results[0].members[5].getExtendedAttribute("SecureContext"), 524 "[SecureContext] should propagate from namespace to method members from partial namespace", 525 ) 526 527 parser = parser.reset() 528 parser.parse( 529 """ 530 namespace TestSecureContextOnNamespace { 531 const octet TEST_CONSTANT = 0; 532 readonly attribute byte testAttribute; 533 undefined testMethod(byte foo); 534 }; 535 [SecureContext] 536 partial namespace TestSecureContextOnNamespace { 537 const octet TEST_CONSTANT_2 = 0; 538 readonly attribute byte testAttribute2; 539 undefined testMethod2(byte foo); 540 }; 541 """ 542 ) 543 results = parser.finish() 544 harness.check( 545 len(results[0].members), 546 6, 547 "TestSecureContextOnNamespace should have six members", 548 ) 549 harness.ok( 550 results[0].getExtendedAttribute("SecureContext") is None, 551 "Namespace should not have [SecureContext] extended attribute", 552 ) 553 harness.ok( 554 results[0].members[0].getExtendedAttribute("SecureContext") is None, 555 ( 556 "[SecureContext] should not propagate from a partial namespace to the namespace's " 557 "constant members" 558 ), 559 ) 560 harness.ok( 561 results[0].members[1].getExtendedAttribute("SecureContext") is None, 562 ( 563 "[SecureContext] should not propagate from a partial namespace to the namespace's " 564 "attribute members" 565 ), 566 ) 567 harness.ok( 568 results[0].members[2].getExtendedAttribute("SecureContext") is None, 569 ( 570 "[SecureContext] should not propagate from a partial namespace to the namespace's " 571 "method members" 572 ), 573 ) 574 harness.ok( 575 results[0].members[3].getExtendedAttribute("SecureContext"), 576 "Constant members from [SecureContext] partial namespace should be [SecureContext]", 577 ) 578 harness.ok( 579 results[0].members[4].getExtendedAttribute("SecureContext"), 580 "Attribute members from [SecureContext] partial namespace should be [SecureContext]", 581 ) 582 harness.ok( 583 results[0].members[5].getExtendedAttribute("SecureContext"), 584 "Method members from [SecureContext] partial namespace should be [SecureContext]", 585 ) 586 587 # Test 'includes'. 588 parser = parser.reset() 589 parser.parse( 590 """ 591 [SecureContext] 592 interface TestSecureContextInterfaceThatIncludesNonSecureContextMixin { 593 const octet TEST_CONSTANT = 0; 594 }; 595 interface mixin TestNonSecureContextMixin { 596 const octet TEST_CONSTANT_2 = 0; 597 readonly attribute byte testAttribute2; 598 undefined testMethod2(byte foo); 599 }; 600 TestSecureContextInterfaceThatIncludesNonSecureContextMixin includes TestNonSecureContextMixin; 601 """ 602 ) 603 results = parser.finish() 604 harness.check( 605 len(results[0].members), 606 4, 607 ( 608 "TestSecureContextInterfaceThatImplementsNonSecureContextInterface should have four " 609 "members" 610 ), 611 ) 612 harness.ok( 613 results[0].getExtendedAttribute("SecureContext"), 614 "Interface should have [SecureContext] extended attribute", 615 ) 616 harness.ok( 617 results[0].members[0].getExtendedAttribute("SecureContext"), 618 ( 619 "[SecureContext] should propagate from interface to constant members even when other " 620 "members are copied from a non-[SecureContext] interface" 621 ), 622 ) 623 harness.ok( 624 results[0].members[1].getExtendedAttribute("SecureContext") is None, 625 "Constants copied from non-[SecureContext] mixin should not be [SecureContext]", 626 ) 627 harness.ok( 628 results[0].members[2].getExtendedAttribute("SecureContext") is None, 629 "Attributes copied from non-[SecureContext] mixin should not be [SecureContext]", 630 ) 631 harness.ok( 632 results[0].members[3].getExtendedAttribute("SecureContext") is None, 633 "Methods copied from non-[SecureContext] mixin should not be [SecureContext]", 634 ) 635 636 parser = parser.reset() 637 parser.parse( 638 """ 639 interface TestSecureContextInterfaceThatIncludesNonSecureContextMixin { 640 const octet TEST_CONSTANT = 0; 641 }; 642 [SecureContext] 643 interface mixin TestNonSecureContextMixin { 644 const octet TEST_CONSTANT_2 = 0; 645 readonly attribute byte testAttribute2; 646 undefined testMethod2(byte foo); 647 }; 648 TestSecureContextInterfaceThatIncludesNonSecureContextMixin includes TestNonSecureContextMixin; 649 """ 650 ) 651 results = parser.finish() 652 harness.check( 653 len(results[0].members), 654 4, 655 ( 656 "TestSecureContextInterfaceThatImplementsNonSecureContextInterface should have four " 657 "members" 658 ), 659 ) 660 harness.ok( 661 results[0].getExtendedAttribute("SecureContext") is None, 662 "Interface should not have [SecureContext] extended attribute", 663 ) 664 harness.ok( 665 results[0].members[0].getExtendedAttribute("SecureContext") is None, 666 ( 667 "[SecureContext] should not propagate from interface to constant members when other " 668 "members are copied from a [SecureContext] mixin" 669 ), 670 ) 671 harness.ok( 672 results[0].members[1].getExtendedAttribute("SecureContext"), 673 "Constants copied from [SecureContext] mixin should be [SecureContext]", 674 ) 675 harness.ok( 676 results[0].members[2].getExtendedAttribute("SecureContext"), 677 "Attributes copied from [SecureContext] mixin should be [SecureContext]", 678 ) 679 harness.ok( 680 results[0].members[3].getExtendedAttribute("SecureContext"), 681 "Methods copied from [SecureContext] mixin should be [SecureContext]", 682 ) 683 684 # Test SecureContext and LegacyNoInterfaceObject 685 parser = parser.reset() 686 parser.parse( 687 """ 688 [LegacyNoInterfaceObject, SecureContext] 689 interface TestSecureContextLegacyNoInterfaceObject { 690 undefined testSecureMethod(byte foo); 691 }; 692 """ 693 ) 694 results = parser.finish() 695 harness.check( 696 len(results[0].members), 697 1, 698 "TestSecureContextLegacyNoInterfaceObject should have only one member", 699 ) 700 harness.ok( 701 results[0].getExtendedAttribute("SecureContext"), 702 "Interface should have [SecureContext] extended attribute", 703 ) 704 harness.ok( 705 results[0].members[0].getExtendedAttribute("SecureContext"), 706 "Interface member should have [SecureContext] extended attribute", 707 )