@@ -76,7 +76,10 @@ def GenValidatorProtoascii(validator_directory, out_dir):
7676 """
7777 logging .info ('entering ...' )
7878
79- protoascii_segments = [open (os .path .join (validator_directory , 'validator-main.protoascii' )).read ()]
79+ protoascii_segments = [
80+ open (os .path .join (validator_directory , 'validator-main.protoascii' )).read (),
81+ open (os .path .join (validator_directory , 'validator-css.protoascii' )).read ()
82+ ]
8083 extensions = glob .glob (os .path .join (validator_directory , '../extensions/*/validator-*.protoascii' ))
8184 extensions .sort ()
8285 for extension in extensions :
@@ -445,10 +448,12 @@ def GetTagSpec(tag_spec, attr_lists):
445448 if isinstance (field_value , (unicode , str , bool , int )):
446449 cdata_dict [ field_descriptor .name ] = field_value
447450 elif isinstance ( field_value , google .protobuf .pyext ._message .RepeatedCompositeContainer ):
448- cdata_dict [ field_descriptor .name ] = {}
451+ cdata_dict [ field_descriptor .name ] = []
449452 for value in field_value :
453+ entry = {}
450454 for (key ,val ) in value .ListFields ():
451- cdata_dict [ field_descriptor .name ][ key .name ] = val
455+ entry [ key .name ] = val
456+ cdata_dict [ field_descriptor .name ].append ( entry )
452457 elif hasattr ( field_value , '_values' ):
453458 cdata_dict [ field_descriptor .name ] = {}
454459 for _value in field_value ._values :
@@ -482,10 +487,11 @@ def GetTagSpec(tag_spec, attr_lists):
482487 cdata_dict ['css_spec' ] = css_spec
483488 if len ( cdata_dict ) > 0 :
484489 if 'blacklisted_cdata_regex' in cdata_dict :
485- if 'error_message' not in cdata_dict ['blacklisted_cdata_regex' ]:
486- raise Exception ( 'Missing error_message for blacklisted_cdata_regex.' );
487- if cdata_dict ['blacklisted_cdata_regex' ]['error_message' ] not in ( 'CSS !important' , 'contents' , 'html comments' ):
488- raise Exception ( 'Unexpected error_message "%s" for blacklisted_cdata_regex.' % cdata_dict ['blacklisted_cdata_regex' ]['error_message' ] );
490+ for entry in cdata_dict ['blacklisted_cdata_regex' ]:
491+ if 'error_message' not in entry :
492+ raise Exception ( 'Missing error_message for blacklisted_cdata_regex.' );
493+ if entry ['error_message' ] not in ( 'contents' , 'html comments' , 'CSS i-amphtml- name prefix' ):
494+ raise Exception ( 'Unexpected error_message "%s" for blacklisted_cdata_regex.' % entry ['error_message' ] );
489495 tag_spec_dict ['cdata' ] = cdata_dict
490496
491497 if 'spec_name' not in tag_spec_dict ['tag_spec' ]:
@@ -674,6 +680,13 @@ def GetAttrs(attrs):
674680
675681 if value_dict is not None :
676682
683+ # Skip rules for dev mode attributes since the AMP plugin will allow them to pass through.
684+ # See <https://github.com/ampproject/amphtml/pull/27174#issuecomment-601391161> for how the rules are
685+ # defined in a way that they can never be satisfied, and thus to make the attribute never allowed.
686+ # This runs contrary to the needs of the AMP plugin, as the internal sanitizers are built to ignore them.
687+ if 'data-ampdevmode' == attr_spec .name :
688+ continue
689+
677690 # Normalize bracketed amp-bind attribute syntax to data-amp-bind-* syntax.
678691 name = attr_spec .name
679692 if name [0 ] == '[' :
0 commit comments