HTML-StripScripts-1.06000755000765000024 012715050062 14603 5ustar00clintonstaff000000000000README100644000765000024 10340112715050062 15603 0ustar00clintonstaff000000000000HTML-StripScripts-1.06NAME HTML::StripScripts - Strip scripting constructs out of HTML SYNOPSIS use HTML::StripScripts; my $hss = HTML::StripScripts->new({ Context => 'Inline' }); $hss->input_start_document; $hss->input_start(''); $hss->input_text('hello, world!'); $hss->input_end(''); $hss->input_end_document; print $hss->filtered_document; DESCRIPTION This module strips scripting constructs out of HTML, leaving as much non-scripting markup in place as possible. This allows web applications to display HTML originating from an untrusted source without introducing XSS (cross site scripting) vulnerabilities. You will probably use HTML::StripScripts::Parser rather than using this module directly. The process is based on whitelists of tags, attributes and attribute values. This approach is the most secure against disguised scripting constructs hidden in malicious HTML documents. As well as removing scripting constructs, this module ensures that there is a matching end for each start tag, and that the tags are properly nested. Previously, in order to customise the output, you needed to subclass "HTML::StripScripts" and override methods. Now, most customisation can be done through the "Rules" option provided to "new()". (See examples/declaration/ and examples/tags/ for cases where subclassing is necessary.) The HTML document must be parsed into start tags, end tags and text before it can be filtered by this module. Use either HTML::StripScripts::Parser or HTML::StripScripts::Regex instead if you want to input an unparsed HTML document. See examples/direct/ for an example of how to feed tokens directly to HTML::StripScripts. CONSTRUCTORS new ( CONFIG ) Creates a new "HTML::StripScripts" filter object, bound to a particular filtering policy. If present, the CONFIG parameter must be a hashref. The following keys are recognized (unrecognized keys will be silently ignored). $s = HTML::Stripscripts->new({ Context => 'Document|Flow|Inline|NoTags', BanList => [qw( br img )] | {br => '1', img => '1'}, BanAllBut => [qw(p div span)], AllowSrc => 0|1, AllowHref => 0|1, AllowRelURL => 0|1, AllowMailto => 0|1, EscapeFiltered => 0|1, Rules => { See below for details }, }); "Context" A string specifying the context in which the filtered document will be used. This influences the set of tags that will be allowed. If present, the "Context" value must be one of: "Document" If "Context" is "Document" then the filter will allow a full HTML document, including the "HTML" tag and "HEAD" and "BODY" sections. "Flow" If "Context" is "Flow" then most of the cosmetic tags that one would expect to find in a document body are allowed, including lists and tables but not including forms. "Inline" If "Context" is "Inline" then only inline tags such as "B" and "FONT" are allowed. "NoTags" If "Context" is "NoTags" then no tags are allowed. The default "Context" value is "Flow". "BanList" If present, this option must be an arrayref or a hashref. Any tag that would normally be allowed (because it presents no XSS hazard) will be blocked if the lowercase name of the tag is in this list. For example, in a guestbook application where "HR" tags are used to separate posts, you may wish to prevent posts from including "HR" tags, even though "HR" is not an XSS risk. "BanAllBut" If present, this option must be reference to an array holding a list of lowercase tag names. This has the effect of adding all but the listed tags to the ban list, so that only those tags listed will be allowed. "AllowSrc" By default, the filter won't allow constructs that cause the browser to fetch things automatically, such as "SRC" attributes in "IMG" tags. If this option is present and true then those constructs will be allowed. "AllowHref" By default, the filter won't allow constructs that cause the browser to fetch things if the user clicks on something, such as the "HREF" attribute in "A" tags. Set this option to a true value to allow this type of construct. "AllowRelURL" By default, the filter won't allow relative URLs such as "../foo.html" in "SRC" and "HREF" attribute values. Set this option to a true value to allow them. "AllowHref" and / or "AllowSrc" also need to be set to true for this to have any effect. "AllowMailto" By default, "mailto:" links are not allowed. If "AllowMailto" is set to a true value, then this construct will be allowed. This can be enabled separately from AllowHref. "EscapeFiltered" By default, any filtered tags are outputted as "". If "EscapeFiltered" is set to a true value, then the filtered tags are converted to HTML entities. For instance:
--> <br> "Rules" The "Rules" option provides a very flexible way of customising the filter. The focus is safety-first, so it is applied after all of the previous validation. This means that you cannot all malicious data should already have been cleared. Rules can be specified for tags and for attributes. Any tag or attribute not explicitly listed will be handled by the default "*" rules. The following is a synopsis of all of the options that you can use to configure rules. Below, an example is broken into sections and explained. Rules => { tag => 0 | 1 | sub { tag_callback } | { attr => 0 | 1 | 'regex' | qr/regex/ | sub { attr_callback}, '*' => 0 | 1 | 'regex' | qr/regex/ | sub { attr_callback}, required => [qw(attrname attrname)], tag => sub { tag_callback } }, '*' => 0 | 1 | sub { tag_callback } | { attr => 0 | 1 | 'regex' | qr/regex/ | sub { attr_callback}, '*' => 0 | 1 | 'regex' | qr/regex/ | sub { attr_callback}, tag => sub { tag_callback } } } EXAMPLE: Rules => { ########################## ##### EXPLICIT RULES ##### ########################## ## Allow
tags, reject tags br => 1, img => 0, ## Send all
tags to a sub div => sub { tag_callback }, ## Allow
tags,and allow the 'cite' attribute ## All other attributes are handled by the default C<*> blockquote => { cite => 1, }, ## Allow tags, and a => { ## Allow the 'title' attribute title => 1, ## Allow the 'href' attribute if it matches the regex href => '^http://yourdomain.com' OR href => qr{^http://yourdomain.com}, ## 'style' attributes are handled by a sub style => sub { attr_callback }, ## All other attributes are rejected '*' => 0, ## Additionally, the tag should be handled by this sub tag => sub { tag_callback}, ## If the tag doesn't have these attributes, filter the tag required => [qw(href title)], }, ########################## ##### DEFAULT RULES ##### ########################## ## The default '*' rule - accepts all the same options as above. ## If a tag or attribute is not mentioned above, then the default ## rule is applied: ## Reject all tags '*' => 0, ## Allow all tags and all attributes '*' => 1, ## Send all tags to the sub '*' => sub { tag_callback }, ## Allow all tags, reject all attributes '*' => { '*' => 0 }, ## Allow all tags, and '*' => { ## Allow the 'title' attribute title => 1, ## Allow the 'href' attribute if it matches the regex href => '^http://yourdomain.com' OR href => qr{^http://yourdomain.com}, ## 'style' attributes are handled by a sub style => sub { attr_callback }, ## All other attributes are rejected '*' => 0, ## Additionally, all tags should be handled by this sub tag => sub { tag_callback}, }, Tag Callbacks sub tag_callback { my ($filter,$element) = (@_); $element = { tag => 'tag', content => 'inner_html', attr => { attr_name => 'attr_value', } }; return 0 | 1; } A tag callback accepts two parameters, the $filter object and the C$element>. It should return 0 to completely ignore the tag and its content (which includes any nested HTML tags), or 1 to accept and output the tag. The $element is a hash ref containing the keys: "tag" This is the tagname in lowercase, eg "a", "br", "img". If you set the tag value to an empty string, then the tag will not be outputted, but the tag contents will. "content" This is the equivalent of DOM's innerHTML. It contains the text content and any HTML tags contained within this element. You can change the content or set it to an empty string so that it is not outputted. "attr" "attr" contains a hashref containing the attribute names and values If for instance, you wanted to replace "" tags with "" tags, you could do this: sub b_callback { my ($filter,$element) = @_; $element->{tag} = 'span'; $element->{attr}{style} = 'font-weight:bold'; return 1; } Attribute Callbacks sub attr_callback { my ( $filter, $tag, $attr_name, $attr_val ) = @_; return undef | '' | 'value'; } Attribute callbacks accept four parameters, the $filter object, the $tag name, the $attr_name and the $attr_value. It should return either "undef" to reject the attribute, or the value to be used. An empty string keeps the attribute, but without a value. "BanList" vs "BanAllBut" vs "Rules" It is not necessary to use "BanList" or "BanAllBut" - everything can be done via "Rules", however it may be simpler to write: BanAllBut => [qw(p div span)] The logic works as follows: * If BanAllBut exists, then ban everything but the tags in the list * Add to the ban list any elements in BanList * Any tags mentioned explicitly in Rules (eg a => 0, br => 1) are added or removed from the BanList * A default rule of { '*' => 0 } would ban all tags except those mentioned in Rules * A default rule of { '*' => 1 } would allow all tags except those disallowed in the ban list, or by explicit rules METHODS This class provides the following methods: hss_init () This method is called by new() and does the actual initialisation work for the new HTML::StripScripts object. input_start_document () This method initializes the filter, and must be called once before starting on each HTML document to be filtered. input_start ( TEXT ) Handles a start tag from the input document. TEXT must be the full text of the tag, including angle-brackets. input_end ( TEXT ) Handles an end tag from the input document. TEXT must be the full text of the end tag, including angle-brackets. input_text ( TEXT ) Handles some non-tag text from the input document. input_process ( TEXT ) Handles a processing instruction from the input document. input_comment ( TEXT ) Handles an HTML comment from the input document. input_declaration ( TEXT ) Handles an declaration from the input document. input_end_document () Call this method to signal the end of the input document. filtered_document () Returns the filtered document as a string. SUBCLASSING The only reason for subclassing this module now is to add to the list of accepted tags, attributes and styles (See "WHITELIST INITIALIZATION METHODS"). Everything else can be achieved with "Rules". The "HTML::StripScripts" class is subclassable. Filter objects are plain hashes and "HTML::StripScripts" reserves only hash keys that start with "_hss". The filter configuration can be set up by invoking the hss_init() method, which takes the same arguments as new(). OUTPUT METHODS The filter outputs a stream of start tags, end tags, text, comments, declarations and processing instructions, via the following "output_*" methods. Subclasses may override these to intercept the filter output. The default implementations of the "output_*" methods pass the text on to the output() method. The default implementation of the output() method appends the text to a string, which can be fetched with the filtered_document() method once processing is complete. If the output() method or the individual "output_*" methods are overridden in a subclass, then filtered_document() will not work in that subclass. output_start_document () This method gets called once at the start of each HTML document passed through the filter. The default implementation does nothing. output_end_document () This method gets called once at the end of each HTML document passed through the filter. The default implementation does nothing. output_start ( TEXT ) This method is used to output a filtered start tag. output_end ( TEXT ) This method is used to output a filtered end tag. output_text ( TEXT ) This method is used to output some filtered non-tag text. output_declaration ( TEXT ) This method is used to output a filtered declaration. output_comment ( TEXT ) This method is used to output a filtered HTML comment. output_process ( TEXT ) This method is used to output a filtered processing instruction. output ( TEXT ) This method is invoked by all of the default "output_*" methods. The default implementation appends the text to the string that the filtered_document() method will return. output_stack_entry ( TEXT ) This method is invoked when a tag plus all text and nested HTML content within the tag has been processed. It adds the tag plus its content to the content for its parent tag. REJECT METHODS When the filter encounters something in the input document which it cannot transform into an acceptable construct, it invokes one of the following "reject_*" methods to put something in the output document to take the place of the unacceptable construct. The TEXT parameter is the full text of the unacceptable construct. The default implementations of these methods output an HTML comment containing the text "filtered". If "EscapeFiltered" is set to true, then the rejected text is HTML escaped instead. Subclasses may override these methods, but should exercise caution. The TEXT parameter is unfiltered input and may contain malicious constructs. reject_start ( TEXT ) reject_end ( TEXT ) reject_text ( TEXT ) reject_declaration ( TEXT ) reject_comment ( TEXT ) reject_process ( TEXT ) WHITELIST INITIALIZATION METHODS The filter refers to various whitelists to determine which constructs are acceptable. To modify these whitelists, subclasses can override the following methods. Each method is called once at object initialization time, and must return a reference to a nested data structure. These references are installed into the object, and used whenever the filter needs to refer to a whitelist. The default implementations of these methods can be invoked as class methods. See examples/tags/ and examples/declaration/ for examples of how to override these methods. init_context_whitelist () Returns a reference to the "Context" whitelist, which determines which tags may appear at each point in the document, and which other tags may be nested within them. It is a hash, and the keys are context names, such as "Flow" and "Inline". The values in the hash are hashrefs. The keys in these subhashes are lowercase tag names, and the values are context names, specifying the context that the tag provides to any other tags nested within it. The special context "EMPTY" as a value in a subhash indicates that nothing can be nested within that tag. init_attrib_whitelist () Returns a reference to the "Attrib" whitelist, which determines which attributes each tag can have and the values that those attributes can take. It is a hash, and the keys are lowercase tag names. The values in the hash are hashrefs. The keys in these subhashes are lowercase attribute names, and the values are attribute value class names, which are short strings describing the type of values that the attribute can take, such as "color" or "number". init_attval_whitelist () Returns a reference to the "AttVal" whitelist, which is a hash that maps attribute value class names from the "Attrib" whitelist to coderefs to subs to validate (and optionally transform) a particular attribute value. The filter calls the attribute value validation subs with the following parameters: "filter" A reference to the filter object. "tagname" The lowercase name of the tag in which the attribute appears. "attrname" The name of the attribute. "attrval" The attribute value found in the input document, in canonical form (see "CANONICAL FORM"). The validation sub can return undef to indicate that the attribute should be removed from the tag, or it can return the new value for the attribute, in canonical form. init_style_whitelist () Returns a reference to the "Style" whitelist, which determines which CSS style directives are permitted in "style" tag attributes. The keys are value names such as "color" and "background-color", and the values are class names to be used as keys into the "AttVal" whitelist. init_deinter_whitelist Returns a reference to the "DeInter" whitelist, which determines which inline tags the filter should attempt to automatically de-interleave if they are encountered interleaved. For example, the filter will transform: hello world ! Into: hello world ! because both "b" and "i" appear as keys in the "DeInter" whitelist. CHARACTER DATA PROCESSING These methods transform attribute values and non-tag text from the input document into canonical form (see "CANONICAL FORM"), and transform text in canonical form into a suitable form for the output document. text_to_canonical_form ( TEXT ) This method is used to reduce non-tag text from the input document to canonical form before passing it to the filter_text() method. The default implementation unescapes all entities that map to "US-ASCII" characters other than ampersand, and replaces any ampersands that don't form part of valid entities with "&". quoted_to_canonical_form ( VALUE ) This method is used to reduce attribute values quoted with doublequotes or singlequotes to canonical form before passing it to the handler subs in the "AttVal" whitelist. The default behavior is the same as that of "text_to_canonical_form()", plus it converts any CR, LF or TAB characters to spaces. unquoted_to_canonical_form ( VALUE ) This method is used to reduce attribute values without quotes to canonical form before passing it to the handler subs in the "AttVal" whitelist. The default implementation simply replaces all ampersands with "&", since that corresponds with the way most browsers treat entities in unquoted values. canonical_form_to_text ( TEXT ) This method is used to convert the text in canonical form returned by the filter_text() method to a form suitable for inclusion in the output document. The default implementation runs anything that doesn't look like a valid entity through the escape_html_metachars() method. canonical_form_to_attval ( ATTVAL ) This method is used to convert the text in canonical form returned by the "AttVal" handler subs to a form suitable for inclusion in doublequotes in the output tag. The default implementation converts CR, LF and TAB characters to a single space, and runs anything that doesn't look like a valid entity through the escape_html_metachars() method. validate_href_attribute ( TEXT ) If the "AllowHref" filter configuration option is set, then this method is used to validate "href" type attribute values. TEXT is the attribute value in canonical form. Returns a possibly modified attribute value (in canonical form) or "undef" to reject the attribute. The default implementation allows only absolute "http" and "https" URLs, permits port numbers and query strings, and imposes reasonable length limits. It does not URI escape the query string, and it does not guarantee properly formatted URIs, it just tries to give safe URIs. You can always use an attribute callback (see "Attribute Callbacks") to provide stricter handling. validate_mailto ( TEXT ) If the "AllowMailto" filter configuration option is set, then this method is used to validate "href" type attribute values which begin with "mailto:". TEXT is the attribute value in canonical form. Returns a possibly modified attribute value (in canonical form) or "undef" to reject the attribute. This uses a lightweight regex and does not guarantee that email addresses are properly formatted. You can always use an attribute callback (see "Attribute Callbacks") to provide stricter handling. validate_src_attribute ( TEXT ) If the "AllowSrc" filter configuration option is set, then this method is used to validate "src" type attribute values. TEXT is the attribute value in canonical form. Returns a possibly modified attribute value (in canonical form) or "undef" to reject the attribute. The default implementation behaves as validate_href_attribute(). OTHER METHODS TO OVERRIDE As well as the output, reject, init and cdata methods listed above, it might make sense for subclasses to override the following methods: filter_text ( TEXT ) This method will be invoked to filter blocks of non-tag text in the input document. Both input and output are in canonical form, see "CANONICAL FORM". The default implementation does no filtering. escape_html_metachars ( TEXT ) This method is used to escape all HTML metacharacters in TEXT. The return value must be a copy of TEXT with metacharacters escaped. The default implementation escapes a minimal set of metacharacters for security against XSS vulnerabilities. The set of characters to escape is a compromise between the need for security and the need to ensure that the filter will work for documents in as many different character sets as possible. Subclasses which make strong assumptions about the document character set will be able to escape much more aggressively. strip_nonprintable ( TEXT ) Returns a copy of TEXT with runs of nonprintable characters replaced with spaces or some other harmless string. Avoids replacing anything with the empty string, as that can lead to other security issues. The default implementation strips out only NULL characters, in order to avoid scrambling text for as many different character sets as possible. Subclasses which make some sort of assumption about the character set in use will be able to have a much wider definition of a nonprintable character, and hence a more secure strip_nonprintable() implementation. ATTRIBUTE VALUE HANDLER SUBS References to the following subs appear in the "AttVal" whitelist returned by the init_attval_whitelist() method. _hss_attval_style( FILTER, TAGNAME, ATTRNAME, ATTRVAL ) Attribute value hander for the "style" attribute. _hss_attval_size ( FILTER, TAGNAME, ATTRNAME, ATTRVAL ) Attribute value handler for attributes who's values are some sort of size or length. _hss_attval_number ( FILTER, TAGNAME, ATTRNAME, ATTRVAL ) Attribute value handler for attributes who's values are a simple integer. _hss_attval_color ( FILTER, TAGNAME, ATTRNAME, ATTRVAL ) Attribute value handler for color attributes. _hss_attval_text ( FILTER, TAGNAME, ATTRNAME, ATTRVAL ) Attribute value handler for text attributes. _hss_attval_word ( FILTER, TAGNAME, ATTRNAME, ATTRVAL ) Attribute value handler for attributes who's values must consist of a single short word, with minus characters permitted. _hss_attval_wordlist ( FILTER, TAGNAME, ATTRNAME, ATTRVAL ) Attribute value handler for attributes who's values must consist of one or more words, separated by spaces and/or commas. _hss_attval_wordlistq ( FILTER, TAGNAME, ATTRNAME, ATTRVAL ) Attribute value handler for attributes who's values must consist of one or more words, separated by commas, with optional doublequotes around words and spaces allowed within the doublequotes. _hss_attval_href ( FILTER, TAGNAME, ATTRNAME, ATTRVAL ) Attribute value handler for "href" type attributes. If the "AllowHref" or "AllowMailto" configuration options are set, uses the validate_href_attribute() method to check the attribute value. _hss_attval_src ( FILTER, TAGNAME, ATTRNAME, ATTRVAL ) Attribute value handler for "src" type attributes. If the "AllowSrc" configuration option is set, uses the validate_src_attribute() method to check the attribute value. _hss_attval_stylesrc ( FILTER, TAGNAME, ATTRNAME, ATTRVAL ) Attribute value handler for "src" type style pseudo attributes. _hss_attval_novalue ( FILTER, TAGNAME, ATTRNAME, ATTRVAL ) Attribute value handler for attributes that have no value or a value that is ignored. Just returns the attribute name as the value. CANONICAL FORM Many of the methods described above deal with text from the input document, encoded in what I call "canonical form", defined as follows: All characters other than ampersands represent themselves. Literal ampersands are encoded as "&". Non "US-ASCII" characters may appear as literals in whatever character set is in use, or they may appear as named or numeric HTML entities such as "æ", "穩" and "ÿ". Unknown named entities such as "&foo;" may appear. The idea is to be able to be able to reduce input text to a minimal form, without making too many assumptions about the character set in use. PRIVATE METHODS The following methods are internal to this class, and should not be invoked from elsewhere. Subclasses should not use or override these methods. _hss_prepare_ban_list (CFG) Returns a hash ref representing all the banned tags, based on the values of BanList and BanAllBut _hss_prepare_rules (CFG) Returns a hash ref representing the tag and attribute rules (See "Rules"). Returns undef if no filters are specified, in which case the attribute filter code has very little performance impact. If any rules are specified, then every tag and attribute is checked. _hss_get_attr_filter ( DEFAULT_FILTERS TAG_FILTERS ATTR_NAME) Returns the attribute filter rule to apply to this particular attribute. Checks for: - a named attribute rule in a named tag - a default * attribute rule in a named tag - a named attribute rule in the default * rules - a default * attribute rule in the default * rules _hss_join_attribs (FILTERED_ATTRIBS) Accepts a hash ref containing the attribute names as the keys, and the attribute values as the values. Escapes them and returns a string ready for output to HTML _hss_decode_numeric ( NUMERIC ) Returns the string that should replace the numeric entity NUMERIC in the text_to_canonical_form() method. _hss_tag_is_banned ( TAGNAME ) Returns true if the lower case tag name TAGNAME is on the list of harmless tags that the filter is configured to block, false otherwise. _hss_get_to_valid_context ( TAG ) Tries to get the filter to a context in which the tag TAG is allowed, by introducing extra end tags or start tags if necessary. TAG can be either the lower case name of a tag or the string 'CDATA'. Returns 1 if an allowed context is reached, or 0 if there's no reasonable way to get to an allowed context and the tag should just be rejected. _hss_close_innermost_tag () Closes the innermost open tag. _hss_context () Returns the current named context of the filter. _hss_valid_in_context ( TAG, CONTEXT ) Returns true if the lowercase tag name TAG is valid in context CONTEXT, false otherwise. _hss_valid_in_current_context ( TAG ) Returns true if the lowercase tag name TAG is valid in the filter's current context, false otherwise. BUGS AND LIMITATIONS Performance This module does a lot of work to ensure that tags are correctly nested and are not left open, causing unnecessary overhead for applications where that doesn't matter. Such applications may benefit from using the more lightweight HTML::Scrubber::StripScripts module instead. Strictness URIs and email addresses are cleaned up to be safe, but not necessarily accurate. That would have required adding dependencies. Attribute callbacks can be used to add this functionality if required, or the validation methods can be overridden. By default, filtered HTML may not be valid strict XHTML, for instance empty required attributes may be outputted. However, with "Rules", it should be possible to force the HTML to validate. REPORTING BUGS Please report any bugs or feature requests to bug-html-stripscripts@rt.cpan.org, or through the web interface at . SEE ALSO HTML::Parser, HTML::StripScripts::Parser, HTML::StripScripts::Regex AUTHOR Original author Nick Cleaton New code added and module maintained by Clinton Gormley COPYRIGHT Copyright (C) 2003 Nick Cleaton. All Rights Reserved. Copyright (C) 2007 Clinton Gormley. All Rights Reserved. LICENSE This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself. Changes100644000765000024 407712715050062 16167 0ustar00clintonstaff000000000000HTML-StripScripts-1.061.06 12 May 2016 Added title tag to elements RT 83302 Fixed a bug in the mailto regex RT 87872 (thanks to ANDK and SysPete) Fixed an unclosed { in the _hss_attval_size regex RT 98110, RT 104221, RT 107247, (thanks to fraserbn, jplesnik, dtenney, and SysPete) Fixed a spelling mistake (thanks to gregoa and SysPete) 1.05 5 Nov 2009 Fixed bug where 'false' but valid content was being ignored, eg "0" became "" See bug https://rt.cpan.org/Public/Bug/Display.html?id=51116 Thanks to Jim Laney for reporting it 1.04 16 Nov 2007 Fixed bug where mailto links not working when AllowHref enabled. (Thanks to Menno Blom - 'b10m'). 1.03 22 Oct 2007 Altered some syntax in a test to make it work in earlier versions of Perl 1.02 22 Oct 2007 Added the examples into the POD 1.01 22 Oct 2007 Fixed the attribute regex to recognise attributes with hyphens eg 'http-equiv' Added examples 1.00 5 Jun 2007 Passed all CPAN tests - bumped version 0.991 29 May 2007 Fixed some Kwalitee issues: - improved META.yml - added Test::Pod and Test::Pod::Coverage tests 0.99 28 May 2007 BanList can now be an array ref or a hash ref Repeated attributes are no longer merged, instead the second value replaces the first Relative URLs can now include query strings Attributes now have CR, LF or TAB replaced by a space Added: - Rules (for customised tag and attribute handling) - EscapeFiltered - AllowMailto - numerous tests 0.03 27 Apr 2004 Added the AllowRelURL option, in response to RT #6123 0.02 25 Jul 2003 Fixed some spelling errors. Added a reference to HTML::Scrubber::StripScripts. 0.01 30 Mar 2003 Initial release. META.yml100644000765000024 126012715050062 16134 0ustar00clintonstaff000000000000HTML-StripScripts-1.06--- abstract: 'Strip scripting constructs out of HTML' author: - 'Clinton Gormley , Nick Cleaton ' build_requires: Test::More: '0' base: '0' configure_requires: ExtUtils::MakeMaker: '0' dynamic_config: 0 generated_by: 'Dist::Zilla version 5.041, CPAN::Meta::Converter version 2.150001' license: perl meta-spec: url: http://module-build.sourceforge.net/META-spec-v1.4.html version: '1.4' name: HTML-StripScripts requires: strict: '0' vars: '0' warnings: '0' resources: bugtracker: https://github.com/clintongormley/perl-html-stripscripts/issues repository: git://github.com/clintongormley/perl-html-stripscripts.git version: '1.06' MANIFEST100644000765000024 112212715050062 16011 0ustar00clintonstaff000000000000HTML-StripScripts-1.06# This file was automatically generated by Dist::Zilla::Plugin::Manifest v5.041. Changes MANIFEST META.json META.yml Makefile.PL README examples/README examples/declaration/MyStripScripts.pm examples/declaration/README examples/declaration/declaration.pl examples/direct/README examples/direct/direct.pl examples/tags/MyStripScripts.pm examples/tags/README examples/tags/tags.pl lib/HTML/StripScripts.pm t/10basic.t t/20config.t t/21input_start.t t/22input_end.t t/30subclass.t t/40bodytext.t t/50rel_url.t t/60rules_tag.t t/61rules_attribs.t t/62rules_callbacks.t t/80pod.t t/81pod_coverage.t t000755000765000024 012715050062 14767 5ustar00clintonstaff000000000000HTML-StripScripts-1.0680pod.t100644000765000024 20112715050062 16217 0ustar00clintonstaff000000000000HTML-StripScripts-1.06/tuse Test::More; eval "use Test::Pod 1.00"; plan skip_all => "Test::Pod 1.00 required for testing POD" if $@; all_pod_files_ok(); META.json100644000765000024 234512715050062 16311 0ustar00clintonstaff000000000000HTML-StripScripts-1.06{ "abstract" : "Strip scripting constructs out of HTML", "author" : [ "Clinton Gormley , Nick Cleaton " ], "dynamic_config" : 0, "generated_by" : "Dist::Zilla version 5.041, CPAN::Meta::Converter version 2.150001", "license" : [ "perl_5" ], "meta-spec" : { "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec", "version" : 2 }, "name" : "HTML-StripScripts", "prereqs" : { "configure" : { "requires" : { "ExtUtils::MakeMaker" : "0" } }, "runtime" : { "requires" : { "strict" : "0", "vars" : "0", "warnings" : "0" } }, "test" : { "requires" : { "Test::More" : "0", "base" : "0" } } }, "release_status" : "stable", "resources" : { "bugtracker" : { "web" : "https://github.com/clintongormley/perl-html-stripscripts/issues" }, "repository" : { "type" : "git", "url" : "git://github.com/clintongormley/perl-html-stripscripts.git", "web" : "https://github.com/clintongormley/perl-html-stripscripts" } }, "version" : "1.06" } 10basic.t100644000765000024 230512715050062 16536 0ustar00clintonstaff000000000000HTML-StripScripts-1.06/t use strict; use Test::More tests => 9; BEGIN { $^W = 1 } use_ok( 'HTML::StripScripts' ); my $f = HTML::StripScripts->new; isa_ok($f, 'HTML::StripScripts'); my $ff = $f->new; isa_ok($f, 'HTML::StripScripts'); $f->input_start_document; $f->input_end_document; is( $f->filtered_document, '', 'empty document' ); $f = HTML::StripScripts->new; $f->input_start_document; $f->input_start(''); $f->input_text('foo'); $f->input_end_document; is( $f->filtered_document, 'foo', 'basic' ); $f->input_start_document; $f->input_start(''); $f->input_text('foo'); $f->input_end_document; is( $f->filtered_document, 'foo', 'second document' ); $f->input_start_document; $f->input_start(''); $f->input_text('foo'); $f->input_end_document; is( $f->filtered_document, 'foo', 'style attribute' ); $f->input_start_document; $f->input_start('foo foo'); $f->input_text('foo'); $f->input_end_document; is( $f->filtered_document, 'foo foofoo', 'img alt' ); $f->input_start_document; $f->input_start(''); $f->input_text('0'); $f->input_end(''); $f->input_end_document; is ($f->filtered_document,'0', 'false but valid content'); Makefile.PL100644000765000024 216112715050062 16636 0ustar00clintonstaff000000000000HTML-StripScripts-1.06# This file was automatically generated by Dist::Zilla::Plugin::MakeMaker v5.041. use strict; use warnings; use ExtUtils::MakeMaker; my %WriteMakefileArgs = ( "ABSTRACT" => "Strip scripting constructs out of HTML", "AUTHOR" => "Clinton Gormley , Nick Cleaton ", "CONFIGURE_REQUIRES" => { "ExtUtils::MakeMaker" => 0 }, "DISTNAME" => "HTML-StripScripts", "LICENSE" => "perl", "NAME" => "HTML::StripScripts", "PREREQ_PM" => { "strict" => 0, "vars" => 0, "warnings" => 0 }, "TEST_REQUIRES" => { "Test::More" => 0, "base" => 0 }, "VERSION" => "1.06", "test" => { "TESTS" => "t/*.t" } ); my %FallbackPrereqs = ( "Test::More" => 0, "base" => 0, "strict" => 0, "vars" => 0, "warnings" => 0 ); unless ( eval { ExtUtils::MakeMaker->VERSION(6.63_03) } ) { delete $WriteMakefileArgs{TEST_REQUIRES}; delete $WriteMakefileArgs{BUILD_REQUIRES}; $WriteMakefileArgs{PREREQ_PM} = \%FallbackPrereqs; } delete $WriteMakefileArgs{CONFIGURE_REQUIRES} unless eval { ExtUtils::MakeMaker->VERSION(6.52) }; WriteMakefile(%WriteMakefileArgs); 20config.t100644000765000024 1535712715050062 16756 0ustar00clintonstaff000000000000HTML-StripScripts-1.06/t use strict; use Test::More tests => 24; BEGIN { $^W = 1 } use HTML::StripScripts; my $f = HTML::StripScripts->new; $f->input_start_document; $f->input_start('

'); $f->input_text('foo'); $f->input_end_document; is( $f->filtered_document, '

foo

', 'default context is Flow' ); $f = HTML::StripScripts->new({ Context => 'Flow' }); $f->input_start_document; $f->input_start('

'); $f->input_text('foo'); $f->input_end_document; is( $f->filtered_document, '

foo

', 'context Flow' ); $f = HTML::StripScripts->new({ Context => 'Inline' }); $f->input_start_document; $f->input_start('

'); $f->input_start(''); $f->input_text('foo'); $f->input_end_document; is( $f->filtered_document, 'foo', 'context Inline' ); $f = HTML::StripScripts->new({ Context => 'NoTags' }); $f->input_start_document; $f->input_start('

'); $f->input_start(''); $f->input_text('foo'); $f->input_end_document; is( $f->filtered_document, 'foo', 'context NoTags' ); $f = HTML::StripScripts->new({ Context => 'Document' }); $f->input_start_document; $f->input_start(''); $f->input_start(''); $f->input_start('

'); $f->input_text('foo'); $f->input_end_document; is( $f->filtered_document, '

foo

', 'context Document' ); $f->input_start_document; $f->input_text('foo'); $f->input_end_document; is( $f->filtered_document, 'foo', 'context Document both' ); $f->input_start_document; $f->input_start(''); $f->input_text('foo'); $f->input_end_document; is( $f->filtered_document, 'foo', 'context Document html' ); $f = HTML::StripScripts->new({ BanList => {'i' => 1, 'p' => 1} }); $f->input_start_document; $f->input_start('

'); $f->input_text('foo'); $f->input_start('

'); $f->input_start('
'); $f->input_start(''); $f->input_start(''); $f->input_text('bar'); $f->input_end_document; is( $f->filtered_document, 'foo
bar', 'BanList takes effect' ); $f = HTML::StripScripts->new({ BanAllBut => [qw(i hr)] }); $f->input_start_document; $f->input_start('

'); $f->input_text('foo'); $f->input_start('

'); $f->input_start('
'); $f->input_start(''); $f->input_start(''); $f->input_text('bar'); $f->input_end_document; is( $f->filtered_document, 'foo
bar', 'BanAllBut takes effect' ); $f = HTML::StripScripts->new({ BanList => {'i' => 1, 'p' => 1}, BanAllBut => [qw(i hr)] }); $f->input_start_document; $f->input_start('

'); $f->input_text('foo'); $f->input_start('

'); $f->input_start('
'); $f->input_start(''); $f->input_start(''); $f->input_text('bar'); $f->input_end_document; is( $f->filtered_document, 'foo
bar', 'BanList beats BanAllBut' ); $f = HTML::StripScripts->new({ BanList => [qw(i p)], BanAllBut => [qw(i hr)]}); $f->input_start_document; $f->input_start('

'); $f->input_text('foo'); $f->input_start('

'); $f->input_start('
'); $f->input_start(''); $f->input_start(''); $f->input_text('bar'); $f->input_end_document; is( $f->filtered_document, 'foo
bar', 'BanList as Array beats BanAllBut' ); $f = HTML::StripScripts->new; $f->input_start_document; $f->input_start(''); $f->input_end_document; is( $f->filtered_document, '', 'AllowSrc defaults to no' ); $f = HTML::StripScripts->new({ AllowSrc => 1 }); $f->input_start_document; $f->input_start(''); $f->input_end_document; is( $f->filtered_document, '', 'AllowSrc yes' ); $f = HTML::StripScripts->new({ AllowSrc => 1 }); $f->input_start_document; $f->input_start(''); $f->input_end_document; is( $f->filtered_document, '', 'AllowSrc checks URL' ); $f = HTML::StripScripts->new; $f->input_start_document; $f->input_start('
'); $f->input_text('foo'); $f->input_end_document; is( $f->filtered_document, 'foo', 'AllowHref defaults to no' ); $f = HTML::StripScripts->new({ AllowHref => 1 }); $f->input_start_document; $f->input_start(''); $f->input_text('foo'); $f->input_end_document; is( $f->filtered_document, 'foo', 'AllowHref yes' ); $f = HTML::StripScripts->new({ AllowHref => 1 }); $f->input_start_document; $f->input_start(''); $f->input_text('foo'); $f->input_end_document; is( $f->filtered_document, 'foo', 'AllowHref checks URL' ); $f = HTML::StripScripts->new({ EscapeFiltered => 1, BanList=>['font'] }); $f->input_start_document; $f->input_start(''); $f->input_text('Text'); $f->input_end(''); $f->input_end_document; is( $f->filtered_document, '<font face="arial">Text</font>', 'EscapeFiltered on' ); $f = HTML::StripScripts->new({ EscapeFiltered => 0, BanList=>['font'] }); $f->input_start_document; $f->input_start(''); $f->input_text('Text'); $f->input_end(''); $f->input_end_document; is( $f->filtered_document, 'Text', 'EscapeFiltered on' ); $f = HTML::StripScripts->new; $f->input_start_document; $f->input_start(''); $f->input_text('foo'); $f->input_end_document; is( $f->filtered_document, 'foo', 'AllowMailto defaults to no' ); $f = HTML::StripScripts->new({ AllowHref => 1 }); $f->input_start_document; $f->input_start(''); $f->input_text('foo'); $f->input_end_document; is( $f->filtered_document, 'foo', "AllowHref doesn't enable mailto's" ); $f = HTML::StripScripts->new({ AllowMailto => 1 }); $f->input_start_document; $f->input_start(''); $f->input_text('foo'); $f->input_end_document; is( $f->filtered_document, 'foo', 'AllowMailto yes' ); $f = HTML::StripScripts->new({ AllowMailto => 1, AllowHref => 1 }); $f->input_start_document; $f->input_start(''); $f->input_text('foo'); $f->input_end_document; is( $f->filtered_document, 'foo', 'AllowMailto + AllowHref works with mailto' ); $f = HTML::StripScripts->new({ AllowMailto => 1, AllowHref => 1 }); $f->input_start_document; $f->input_start(''); $f->input_text('foo'); $f->input_end_document; is( $f->filtered_document, 'foo', 'AllowMailto + AllowHref works with http' ); 50rel_url.t100644000765000024 303612715050062 17127 0ustar00clintonstaff000000000000HTML-StripScripts-1.06/t use strict; use Test::More tests => 12; BEGIN { $^W = 1 } use HTML::StripScripts; my $f = HTML::StripScripts->new({ AllowHref => 1 }); my $allow_rel = 0; mytest( '', 'x', 'malicious' ); mytest( '', 'x', 'garbage' ); mytest( '', 'x', 'absolute' ); mytest( '', 'x', 'full' ); mytest( '', 'x', 'relative' ); mytest( '', 'x', 'relative ..' ); $allow_rel = 1; $f = HTML::StripScripts->new({ AllowHref => 1, AllowRelURL => 1 }); mytest( '', 'x', 'malicious' ); mytest( '', 'x', 'garbage' ); mytest( '', 'x', 'absolute' ); mytest( '', 'x', 'full' ); mytest( '', 'x', 'relative' ); mytest( '', 'x', 'relative ..' ); sub mytest { my ($in, $out, $name) = @_; $f->input_start_document; $f->input_start($in); $f->input_text('x'); $f->input_end_document; is( $f->filtered_document, $out, ($allow_rel ? 'yes' : 'no') . " rel $name" ); } 30subclass.t100644000765000024 3566412715050062 17334 0ustar00clintonstaff000000000000HTML-StripScripts-1.06/t use strict; use Test::More tests => 27; BEGIN { $^W = 1 } use HTML::StripScripts; =head1 name F - HTML::StripScripts subclassing test script =head1 DESCRIPTION This file is part of the reggression test suite of L, testing that subclassing works as documented. This file also serves as a set of examples of subclassing L. =head1 TESTS =over =item output_start_document Overriding output_start_document() to prepend an HTML comment. =cut { package SubClass_output_start_document; use base qw(HTML::StripScripts); sub output_start_document { my ($self) = @_; $self->output_comment(''); } } my $f = SubClass_output_start_document->new; $f->input_start_document; $f->input_text('foo'); $f->input_end_document; is( $f->filtered_document, 'foo', 'subclass output_start_document' ); =item output_end_document Overriding output_end_document() to apend an HTML comment. =cut { package SubClass_output_end_document; use base qw(HTML::StripScripts); sub output_end_document { my ($self) = @_; $self->output_comment(''); } } $f = SubClass_output_end_document->new; $f->input_start_document; $f->input_text('foo'); $f->input_end_document; is( $f->filtered_document, 'foo', 'subclass output_end_document' ); =item output_start Overriding output_start() to convert start tags to upper case =cut { package SubClass_output_start; use base qw(HTML::StripScripts); sub output_start { my ($self, $text) = @_; $self->output(uc $text); } } $f = SubClass_output_start->new; $f->input_start_document; $f->input_start(''); $f->input_text('foo'); $f->input_end_document; is( $f->filtered_document, 'foo', 'subclass output_start' ); =item output_text Overriding output_text() to convert text to upper case =cut { package SubClass_output_text; use base qw(HTML::StripScripts); sub output_text { my ($self, $text) = @_; $self->output(uc $text); } } $f = SubClass_output_text->new; $f->input_start_document; $f->input_start(''); $f->input_text('foo'); $f->input_end_document; is( $f->filtered_document, 'FOO', 'subclass output_text' ); =item output_end Overriding output_end() to convert end tags to upper case =cut { package SubClass_output_end; use base qw(HTML::StripScripts); sub output_end { my ($self, $text) = @_; $self->output(uc $text); } } $f = SubClass_output_end->new; $f->input_start_document; $f->input_start(''); $f->input_text('foo'); $f->input_end_document; is( $f->filtered_document, 'foo', 'subclass output_end' ); =item output Overriding output() to convert all output to upper case =cut { package SubClass_output; use base qw(HTML::StripScripts); sub output { my ($self, $text) = @_; $self->SUPER::output(uc $text); } } $f = SubClass_output->new; $f->input_start_document; $f->input_start(''); $f->input_text('foo'); $f->input_end_document; is( $f->filtered_document, 'FOO', 'subclass output' ); =item reject_start Overriding reject_start() so that rejected start tags are escaped rather than replaced with HTML comments. =cut { package SubClass_reject_start; use base qw(HTML::StripScripts); sub reject_start { my ($self, $text) = @_; $self->output_text( $self->escape_html_metachars($text) ); } } $f = SubClass_reject_start->new; $f->input_start_document; $f->input_start(''); $f->input_text('foo'); $f->input_end_document; is( $f->filtered_document, '<foo type=bar>foo', 'subclass reject start' ); =item reject_end Overriding reject_end() so that rejected end tags are escaped rather than replaced with HTML comments. =cut { package SubClass_reject_end; use base qw(HTML::StripScripts); sub reject_end { my ($self, $text) = @_; $self->output_text( $self->escape_html_metachars($text) ); } } $f = SubClass_reject_end->new; $f->input_start_document; $f->input_text('foo'); $f->input_end(''); $f->input_end_document; is( $f->filtered_document, 'foo</i>', 'subclass reject end' ); =item reject_text Overriding reject_text() so that rejected non-tag text is replaced with a different HTML comment than the default. =cut { package SubClass_reject_text; use base qw(HTML::StripScripts); sub reject_text { my ($self, $text) = @_; $self->output_comment(''); } } $f = SubClass_reject_text->new({ Context => 'Document' }); $f->input_start_document; $f->input_start(''); $f->input_start(''); $f->input_text('bah'); $f->input_end(''); $f->input_text('foo'); $f->input_end_document; is( $f->filtered_document, 'foo', 'subclass reject_text' ); =item reject_decalaration Overriding reject_decalaration() so that rejected declarations are replaced with custom text. =cut { package SubClass_reject_declaration; use base qw(HTML::StripScripts); sub reject_declaration { my ($self, $text) = @_; $self->output_declaration(''); } } $f = SubClass_reject_declaration->new; $f->input_start_document; $f->input_declaration(''); $f->input_text('foo'); $f->input_end_document; is( $f->filtered_document, 'foo', 'subclass reject_decalaration' ); =item reject_comment Overriding reject_comment() so that rejected HTML comments are replaced with custom text. =cut { package SubClass_reject_comment; use base qw(HTML::StripScripts); sub reject_comment { my ($self, $text) = @_; $self->output_comment(''); } } $f = SubClass_reject_comment->new; $f->input_start_document; $f->input_text('foo'); $f->input_comment(''); $f->input_text('foo'); $f->input_end_document; is( $f->filtered_document, 'foofoo', 'subclass reject_comment' ); =item reject_process Overriding reject_process() so that rejected processing instructions are replaced with custom text. =cut { package SubClass_reject_process; use base qw(HTML::StripScripts); sub reject_process { my ($self, $text) = @_; $self->output_process(''); } } $f = SubClass_reject_process->new; $f->input_start_document; $f->input_process(''); $f->input_text('foo'); $f->input_end_document; is( $f->filtered_document, 'foo', 'subclass reject_process' ); =item init_context_whitelist Overriding init_context_whitelist() so that the filter will allow C tags only at C level. =cut { package SubClass_init_context_whitelist; use base qw(HTML::StripScripts); use vars qw(%_Context); %_Context = %{ __PACKAGE__->SUPER::init_context_whitelist }; foreach my $ctx (keys %_Context) { next if $ctx eq 'Flow'; next unless exists $_Context{$ctx}{'ins'}; # Found a context other than 'Flow' that allows ins tags. Take # a deeper copy of this part of the context hash before deleting # 'ins' from it, to avoid messing with the readonly structure we # were passed. $_Context{$ctx} = { %{ $_Context{$ctx} } }; delete $_Context{$ctx}{'ins'}; } sub init_context_whitelist { my ($self) = @_; return \%_Context; } } $f = SubClass_init_context_whitelist->new; $f->input_start_document; $f->input_start(''); $f->input_text('foo'); $f->input_end(''); $f->input_start(''); $f->input_start(''); $f->input_text('foo'); $f->input_end(''); $f->input_end_document; is( $f->filtered_document, 'foofoo', 'subclass init_context_whitelist' ); $f = HTML::StripScripts->new; $f->input_start_document; $f->input_start(''); $f->input_text('foo'); $f->input_end(''); $f->input_start(''); $f->input_start(''); $f->input_text('foo'); $f->input_end(''); $f->input_end_document; is( $f->filtered_document, 'foofoo', "subclass init_context_whitelist didn't break superclass" ); =item init_attrib_whitelist Overriding init_attrib_whitelist() so that the filter will not allow C
tags to have the C attribute. =cut { package SubClass_init_attrib_whitelist; use base qw(HTML::StripScripts); use vars qw(%_Attrib); %_Attrib = %{ __PACKAGE__->SUPER::init_attrib_whitelist }; $_Attrib{'br'} = { %{ $_Attrib{'br'} } }; delete $_Attrib{'br'}{'clear'}; sub init_attrib_whitelist { my ($self) = @_; return \%_Attrib; } } $f = SubClass_init_attrib_whitelist->new; $f->input_start_document; $f->input_start('
'); $f->input_end_document; is( $f->filtered_document, '
', 'subclass init_attrib_whitelist' ); $f = HTML::StripScripts->new; $f->input_start_document; $f->input_start('
'); $f->input_end_document; is( $f->filtered_document, '
', "subclass init_attrib_whitelist didn't break superclass" ); =item init_attval_whitelist Overriding init_attval_whitelist() so that the color value C is replaced with C. =cut { package SubClass_init_attval_whitelist; use base qw(HTML::StripScripts); use vars qw(%_AttVal); %_AttVal = %{ __PACKAGE__->SUPER::init_attval_whitelist }; my $super = $_AttVal{'color'}; $_AttVal{'color'} = sub { my ($filter, $tag, $attname, $attval) = @_; $attval =~ s/pink/blue/i; &{ $super }($filter, $tag, $attname, $attval); }; sub init_attval_whitelist { my ($self) = @_; return \%_AttVal; } } $f = SubClass_init_attval_whitelist->new; $f->input_start_document; $f->input_start(''); $f->input_text('foo'); $f->input_end_document; is( $f->filtered_document, 'foo', 'subclass init_attval_whitelist' ); $f->input_start_document; $f->input_start(''); $f->input_text('foo'); $f->input_end_document; is( $f->filtered_document, 'foo', 'subclass init_attval_whitelist deobfuscate pink' ); $f = HTML::StripScripts->new; $f->input_start_document; $f->input_start(''); $f->input_text('foo'); $f->input_end_document; is( $f->filtered_document, 'foo', "subclass init_attval_whitelist didn't break superclass" ); =item init_style_whitelist Overriding init_style_whitelist() so that the C style attribute is not allowed. =cut { package SubClass_init_style_whitelist; use base qw(HTML::StripScripts); use vars qw(%_Style); %_Style = %{ __PACKAGE__->SUPER::init_style_whitelist }; delete $_Style{'background-color'}; sub init_style_whitelist { my ($self) = @_; return \%_Style; } } $f = SubClass_init_style_whitelist->new; $f->input_start_document; $f->input_start(''); $f->input_text('foo'); $f->input_end_document; is( $f->filtered_document, 'foo', 'subclass init_style_whitelist' ); $f = HTML::StripScripts->new; $f->input_start_document; $f->input_start(''); $f->input_text('foo'); $f->input_end_document; is( $f->filtered_document, 'foo', "subclass init_style_whitelist didn't break superclass" ); =item init_deinter_whitelist Overriding init_deinter_whitelist() so that the C tag will not be autodeinterleaved. =cut { package SubClass_init_deinter_whitelist; use base qw(HTML::StripScripts); use vars qw(%_DeInter); %_DeInter = %{ __PACKAGE__->SUPER::init_deinter_whitelist }; delete $_DeInter{'font'}; sub init_deinter_whitelist { my ($self) = @_; return \%_DeInter; } } $f = SubClass_init_deinter_whitelist->new; $f->input_start_document; $f->input_start(''); $f->input_text('foo'); $f->input_start(''); $f->input_text('bar'); $f->input_end(''); $f->input_text('baz'); $f->input_end_document; is( $f->filtered_document, 'foobarbaz', 'subclass init_deinter_whitelist' ); $f = HTML::StripScripts->new; $f->input_start_document; $f->input_start(''); $f->input_text('foo'); $f->input_start(''); $f->input_text('bar'); $f->input_end(''); $f->input_text('baz'); $f->input_end_document; is( $f->filtered_document, 'foobarbaz', "subclass init_style_whitelist didn't break superclass" ); =item validate_href_attribute Overriding validate_href_attribute() so that relative as well as absolute links will be accepted. =cut { package SubClass_validate_href_attribute; use base qw(HTML::StripScripts); sub validate_href_attribute { my ($self, $text) = @_; $text =~ m#^([\w\./\-]{2,100})$# ? $1 : $self->SUPER::validate_href_attribute($text); } } $f = SubClass_validate_href_attribute->new({ AllowHref => 1 }); $f->input_start_document; $f->input_start(''); $f->input_text('foo'); $f->input_end_document; is( $f->filtered_document, 'foo', 'subclass validate_href_attribute' ); =item filter_text Overriding filter_text() to convert text to upper case =cut { package SubClass_filter_text; use base qw(HTML::StripScripts); sub filter_text { my ($self, $text) = @_; return uc $text; } } $f = SubClass_filter_text->new; $f->input_start_document; $f->input_start(''); $f->input_text('foo'); $f->input_end_document; is( $f->filtered_document, 'FOO', 'subclass filter_text' ); =item escape_html_metachars Overriding escape_html_metachars() to convert escape more aggressively =cut { package SubClass_escape_html_metachars; use base qw(HTML::StripScripts); sub escape_html_metachars { my ($self, $text) = @_; $text =~ s|([<>"'&\200-\377])| sprintf '&#%d;', ord $1 |ge; return $text; } } $f = SubClass_escape_html_metachars->new; $f->input_start_document; $f->input_start(qq{<foo \xff>}); $f->input_end_document; is( $f->filtered_document, '<foo ÿ>', 'subclass escape_html_metachars' ); =item strip_nonprintable Overriding strip_nonprintable() to strip more aggressively =back =cut { package SubClass_strip_nonprintable; use base qw(HTML::StripScripts); sub strip_nonprintable { my ($self, $text) = @_; $text =~ tr#\000-\007# #s; return $text; } } $f = SubClass_strip_nonprintable->new; $f->input_start_document; $f->input_start(qq{<foo \xff\x01\x05>}); $f->input_end_document; is( $f->filtered_document, qq{<foo \xff >}, 'subclass escape_html_metachars' ); 40bodytext.t100644000765000024 506512715050062 17330 0ustar00clintonstaff000000000000HTML-StripScripts-1.06/t use strict; use vars qw(@tests); BEGIN { $^W = 1; @tests = ( [ '', '' ], [ ''', ''' ], [ '&amp;', '&amp;' ], [ '&amp;', '&amp;' ], [ '&*', '&*' ], [ '穩', '穩' ], [ 'ő', 'ő' ], [ '', '' ], [ '', '' ], [ '', '' ], [ '', '' ], [ '&foo;', '&foo;' ], [ '&Foo3;', '&Foo3;' ], [ "\0", ' ' ], ); foreach my $pair ( ['<','<'], ['>','>'], ['&','&'], ['"','"'], ["'",'''], ['a','a'], ) { my ($in, $out) = @$pair; push @tests, [ $in, $out ]; push @tests, [ $out, $out ]; my $dec = ord $in; push @tests, [ "&#$dec;", $out ]; push @tests, [ "�$dec;", $out ]; push @tests, [ "�$dec;", $out ]; my $hex = sprintf '%x', $dec; push @tests, [ "&#x$hex;", $out ]; push @tests, [ "&#X$hex;", $out ]; push @tests, [ "�$hex;", $out ]; push @tests, [ "�$hex;", $out ]; push @tests, [ "�$hex;", $out ]; push @tests, [ "�$hex;", $out ]; if ($hex =~ /[a-f]/) { $hex = uc $hex; push @tests, [ "&#x$hex;", $out ]; push @tests, [ "&#X$hex;", $out ]; push @tests, [ "�$hex;", $out ]; push @tests, [ "�$hex;", $out ]; push @tests, [ "�$hex;", $out ]; push @tests, [ "�$hex;", $out ]; } } } use Test::More tests => 4 * scalar(@tests); use HTML::StripScripts; my $f = HTML::StripScripts->new; foreach my $test (@tests) { my ($in, $out) = @$test; $f->input_start_document; $f->input_text($in); $f->input_end_document; is( $f->filtered_document, $out, "text input [$in]" ); $f->input_start_document; $f->input_text("=$in="); $f->input_end_document; is( $f->filtered_document, "=$out=", "text input [=$in=]" ); my $esc = $in; $esc =~ s/"/"/g; $f->input_start_document; $f->input_start(qq{$esc}); $f->input_end_document; is( $f->filtered_document, qq{$out}, "img alt input [$in]" ); $f->input_start_document; $f->input_start(qq{=$esc=}); $f->input_end_document; is( $f->filtered_document, qq{=$out=}, "img alt input [=$in=]" ); } examples000755000765000024 012715050062 16342 5ustar00clintonstaff000000000000HTML-StripScripts-1.06README100644000765000024 54412715050062 17345 0ustar00clintonstaff000000000000HTML-StripScripts-1.06/examplesCheck the README in each directory for an explanation of the example. - examples/direct - Using HTML::StripScripts directly - examples/tags - Overriding HTML::StripScripts to add the and tags into the definition for - examples/declaration - Overriding HTML::StripScripts to allow DDTs (Document Type Declarations) 22input_end.t100644000765000024 142612715050062 17450 0ustar00clintonstaff000000000000HTML-StripScripts-1.06/t use strict; use Test::More tests => 7; BEGIN { $^W = 1 } use HTML::StripScripts; my $f = HTML::StripScripts->new; mytest( '', '
', 'reject null' ); mytest( '', '
', 'reject empty' ); mytest( '', '', 'reject malformed' ); mytest( '','', 'reject unknown' ); mytest( '
', '', 'reject misplaced' ); mytest( '', '', 'accept valid' ); mytest( '', '', 'accept uppercase' ); sub mytest { my ($in, $out, $name) = @_; $f->input_start_document; $f->input_start(''); $f->input_text('foo'); $f->input_end($in); $f->input_end_document; is( $f->filtered_document, "foo$out", "input_end $name" ); } 60rules_tag.t100644000765000024 1217712715050062 17477 0ustar00clintonstaff000000000000HTML-StripScripts-1.06/tuse strict; use Test::More tests => 48; BEGIN { $^W = 1 } use HTML::StripScripts; my %tags_b = ( 'undef' => undef, '0' => 0, '1' => 1, 'sub' => \&b_callback, 'hash' => {}, 'tag_sub' => { tag => \&b_callback } ); my %tags_default = ( 'undef' => undef, '0' => 0, '1' => 1, 'sub' => \&default_callback, 'hash' => {}, 'tag_0' => { tag => 0 }, 'tag_1' => { tag => 1 }, 'tag_sub' => { tag => \&default_callback } ); my %results; foreach my $b (qw(undef 0 1 sub hash tag_sub)) { foreach my $default (qw(undef 0 1 sub hash tag_0 tag_1 tag_sub)) { my $test = "${b} :: ${default}"; test_tag( $test, $tags_b{$b}, $tags_default{$default}, $results{$test} ); } } #=================================== sub test_tag { #=================================== my ( $test, $b, $default, $result ) = @_; my %Rules; if ( defined $b ) { $Rules{'b'} = $b; } if ( defined $default ) { $Rules{'*'} = $default; } my $f = HTML::StripScripts->new( { Rules => \%Rules } ); $f->input_start_document; $f->input_start(''); $f->input_text('foo'); $f->input_end(''); $f->input_start(''); $f->input_text('bar'); $f->input_end(''); $f->input_end_document; is( $f->filtered_document, $result, "$test" ); } #=================================== sub b_callback { #=================================== my ( $filter, $e ) = @_; $e->{content} = "[B : tag='$e->{tag}', content='$e->{content}']" . $e->{content}; return 1; } #=================================== sub default_callback { #=================================== my ( $filter, $e ) = @_; $e->{content} = "[DEFAULT : tag='$e->{tag}', content='$e->{content}']" . $e->{content}; return 1; } BEGIN { my $filt = ''; my $def_b = "[DEFAULT : tag='b', content='foo']"; my $def_i = "[DEFAULT : tag='i', content='bar']"; my $b = "[B : tag='b', content='foo']"; %results = ( 'undef :: undef' => "foobar", 'undef :: 0' => "${filt}foo${filt}${filt}bar${filt}", 'undef :: 1' => "foobar", 'undef :: sub' => "${def_b}foo${def_i}bar", 'undef :: hash' => "foobar", 'undef :: tag_0' => "${filt}foo${filt}${filt}bar${filt}", 'undef :: tag_1' => "foobar", 'undef :: tag_sub' => "${def_b}foo${def_i}bar", '0 :: undef' => "${filt}foo${filt}bar", '0 :: 0' => "${filt}foo${filt}${filt}bar${filt}", '0 :: 1' => "${filt}foo${filt}bar", '0 :: sub' => "${filt}foo${filt}${def_i}bar", '0 :: hash' => "${filt}foo${filt}bar", '0 :: tag_0' => "${filt}foo${filt}${filt}bar${filt}", '0 :: tag_1' => "${filt}foo${filt}bar", '0 :: tag_sub' => "${filt}foo${filt}${def_i}bar", '1 :: undef' => "foobar", '1 :: 0' => "foo${filt}bar${filt}", '1 :: 1' => "foobar", '1 :: sub' => "${def_b}foo${def_i}bar", '1 :: hash' => "foobar", '1 :: tag_0' => "foo${filt}bar${filt}", '1 :: tag_1' => "foobar", '1 :: tag_sub' => "${def_b}foo${def_i}bar", 'sub :: undef' => "${b}foobar", 'sub :: 0' => "${b}foo${filt}bar${filt}", 'sub :: 1' => "${b}foobar", 'sub :: sub' => "${b}foo${def_i}bar", 'sub :: hash' => "${b}foobar", 'sub :: tag_0' => "${b}foo${filt}bar${filt}", 'sub :: tag_1' => "${b}foobar", 'sub :: tag_sub' => "${b}foo${def_i}bar", 'hash :: undef' => "foobar", 'hash :: 0' => "foo${filt}bar${filt}", 'hash :: 1' => "foobar", 'hash :: sub' => "${def_b}foo${def_i}bar", 'hash :: hash' => "foobar", 'hash :: tag_0' => "foo${filt}bar${filt}", 'hash :: tag_1' => "foobar", 'hash :: tag_sub' => "${def_b}foo${def_i}bar", 'tag_sub :: undef' => "${b}foobar", 'tag_sub :: 0' => "${b}foo${filt}bar${filt}", 'tag_sub :: 1' => "${b}foobar", 'tag_sub :: sub' => "${b}foo${def_i}bar", 'tag_sub :: hash' => "${b}foobar", 'tag_sub :: tag_0' => "${b}foo${filt}bar${filt}", 'tag_sub :: tag_1' => "${b}foobar", 'tag_sub :: tag_sub' => "${b}foo${def_i}bar", ); } 21input_start.t100644000765000024 300312715050062 20027 0ustar00clintonstaff000000000000HTML-StripScripts-1.06/t use strict; use Test::More tests => 15; BEGIN { $^W = 1 } use HTML::StripScripts; my $f = HTML::StripScripts->new; mytest( '', '', 'reject null' ); mytest( '<>', '', 'reject empty' ); mytest( '<->', '', 'reject malformed' ); mytest( '', '', 'reject unknown' ); mytest( '', '', 'ignore trailing junk' ); mytest( 'foo', 'bar', 'overwrite repeated values' ); mytest( 'bar', 'bar', 'allow squashed values' ); mytest( q{foo}, 'foo', 'accept singlequotes' ); mytest( 'foo', 'foo', 'accept unquoted' ); mytest( q{<foo}, '<foo', 'allow < in singlequotes' ); mytest( '<foo', '<foo', 'allow < in doublequotes' ); mytest( '<foo', '&lt;foo', 'reject unquoted entity' ); mytest( '&foo-bar;', '&foo-bar;', 'reject malformed entity' ); mytest( '
', '
', 'accept valueless attribute' ); mytest( '
', '
', 'rewrite valueless attribute' ); sub mytest { my ($in, $out, $name) = @_; $f->input_start_document; $f->input_start($in); $f->input_end_document; is( $f->filtered_document, $out, "input_start $name" ); } 81pod_coverage.t100644000765000024 33012715050062 20076 0ustar00clintonstaff000000000000HTML-StripScripts-1.06/tuse Test::More; eval "use Test::Pod::Coverage tests=>1"; plan skip_all => "Test::Pod::Coverage required for testing POD coverage" if $@; pod_coverage_ok( "HTML::StripScripts", "HTML::StripScripts is covered" ); 61rules_attribs.t100644000765000024 42600612715050062 20415 0ustar00clintonstaff000000000000HTML-StripScripts-1.06/tuse strict; use Test::More tests => 1372; BEGIN { $^W = 1; eval "require Data::Dumper; import Data::Dumper"; $@ and eval "sub Dumper {'Install Data::Dumper for detailed diagnostics'}"; } use HTML::StripScripts; my %attrs_def_al = my %attrs_def_def = my %attrs_img_al = my %attrs_img_def = ( 'undef' => undef, '0' => 0, '1' => 1, 'string' => '^foo$', 'regex' => qr/^foo$/, 'sub' => \&img_def_callback ); $attrs_def_al{sub} = \&def_al_callback; $attrs_def_def{sub} = \&def_def_callback; $attrs_img_al{sub} = \&img_al_callback; ## test attribute rules with fallback to * my @order = qw(undef 0 1 string regex sub); my %results; foreach my $img_tag ( 0, 1 ) { foreach my $def_tag ( 0, 1 ) { foreach my $img_al ( $img_tag ? @order : '' ) { foreach my $img_def ( $img_tag ? @order : '' ) { foreach my $def_al ( $def_tag ? @order : '' ) { foreach my $def_def ( $def_tag ? @order : '' ) { my %Rules; my $test = '[img::'; if ($img_tag) { $test .= "${img_al}:${img_def}]"; $Rules{img}{align} = $attrs_img_al{$img_al} unless $img_al eq 'undef'; $Rules{img}{'*'} = $attrs_img_def{$img_def} unless $img_def eq 'undef'; } else { $test .= 'none]'; } $test .= '[*::'; if ($def_tag) { $test .= "${def_al}:${def_def}]"; $Rules{'*'}{align} = $attrs_def_al{$def_al} unless $def_al eq 'undef'; $Rules{'*'}{'*'} = $attrs_def_def{$def_def} unless $def_def eq 'undef'; } else { $test .= 'none]'; } test_attrs( $test, \%Rules, $results{$test} ); } } } } } } ## test required attributes test_attrs( 'required_ok', { img => { required => [qw(alt align)] } }, 'bar

' ); test_attrs( 'required_not_ok_1', { img => { required => [qw(title)] } }, '

' ); test_attrs( 'required_not_ok_2', { img => { required => [qw(alt title)] } }, '

' ); #=================================== sub test_attrs { #=================================== my ( $test, $Rules, $result ) = @_; my $f = HTML::StripScripts->new( { Rules => $Rules } ); $f->input_start_document; $f->input_start('bar'); $f->input_start('

'); $f->input_end('

'); $f->input_end_document; is( $f->filtered_document, $result, "$test" ) or diag( Dumper( $Rules, $f->{_hssRules} ) ); } #=================================== sub img_al_callback { #=================================== my ( $filter, $tag, $attr, $val, $sub ) = @_; $sub ||= 'img_al'; return "[$sub : $tag : $attr : $val]"; } sub img_def_callback { return img_al_callback( @_, 'img_def' ) } sub def_al_callback { return img_al_callback( @_, 'def_al' ) } sub def_def_callback { return img_al_callback( @_, 'def_def' ) } BEGIN { my $ia_ial = "[img_al : img : align : foo]"; my $id_ial = "[img_def : img : align : foo]"; my $id_iat = "[img_def : img : alt : bar]"; my $da_ial = "[def_al : img : align : foo]"; my $da_hal = "[def_al : h1 : align : foo]"; my $dd_ial = "[def_def : img : align : foo]"; my $dd_iat = "[def_def : img : alt : bar]"; my $dd_hal = "[def_def : h1 : align : foo]"; %results = ( '[img::none][*::none]' => qq{bar

}, '[img::none][*::undef:undef]' => qq{bar

}, '[img::none][*::undef:0]' => qq{

}, '[img::none][*::undef:1]' => qq{bar

}, '[img::none][*::undef:string]' => qq{

}, '[img::none][*::undef:regex]' => qq{

}, '[img::none][*::undef:sub]' => qq{${dd_iat}

}, '[img::none][*::0:undef]' => qq{bar

}, '[img::none][*::0:0]' => qq{

}, '[img::none][*::0:1]' => qq{bar

}, '[img::none][*::0:string]' => qq{

}, '[img::none][*::0:regex]' => qq{

}, '[img::none][*::0:sub]' => qq{${dd_iat}

}, '[img::none][*::1:undef]' => qq{bar

}, '[img::none][*::1:0]' => qq{

}, '[img::none][*::1:1]' => qq{bar

}, '[img::none][*::1:string]' => qq{

}, '[img::none][*::1:regex]' => qq{

}, '[img::none][*::1:sub]' => qq{${dd_iat}

}, '[img::none][*::string:undef]' => qq{bar

}, '[img::none][*::string:0]' => qq{

}, '[img::none][*::string:1]' => qq{bar

}, '[img::none][*::string:string]' => qq{

}, '[img::none][*::string:regex]' => qq{

}, '[img::none][*::string:sub]' => qq{${dd_iat}

}, '[img::none][*::regex:undef]' => qq{bar

}, '[img::none][*::regex:0]' => qq{

}, '[img::none][*::regex:1]' => qq{bar

}, '[img::none][*::regex:string]' => qq{

}, '[img::none][*::regex:regex]' => qq{

}, '[img::none][*::regex:sub]' => qq{${dd_iat}

}, '[img::none][*::sub:undef]' => qq{bar

}, '[img::none][*::sub:0]' => qq{

}, '[img::none][*::sub:1]' => qq{bar

}, '[img::none][*::sub:string]' => qq{

}, '[img::none][*::sub:regex]' => qq{

}, '[img::none][*::sub:sub]' => qq{${dd_iat}

}, '[img::undef:undef][*::none]' => qq{bar

}, '[img::undef:0][*::none]' => qq{

}, '[img::undef:1][*::none]' => qq{bar

}, '[img::undef:string][*::none]' => qq{

}, '[img::undef:regex][*::none]' => qq{

}, '[img::undef:sub][*::none]' => qq{${id_iat}

}, '[img::0:undef][*::none]' => qq{bar

}, '[img::0:0][*::none]' => qq{

}, '[img::0:1][*::none]' => qq{bar

}, '[img::0:string][*::none]' => qq{

}, '[img::0:regex][*::none]' => qq{

}, '[img::0:sub][*::none]' => qq{${id_iat}

}, '[img::1:undef][*::none]' => qq{bar

}, '[img::1:0][*::none]' => qq{

}, '[img::1:1][*::none]' => qq{bar

}, '[img::1:string][*::none]' => qq{

}, '[img::1:regex][*::none]' => qq{

}, '[img::1:sub][*::none]' => qq{${id_iat}

}, '[img::string:undef][*::none]' => qq{bar

}, '[img::string:0][*::none]' => qq{

}, '[img::string:1][*::none]' => qq{bar

}, '[img::string:string][*::none]' => qq{

}, '[img::string:regex][*::none]' => qq{

}, '[img::string:sub][*::none]' => qq{${id_iat}

}, '[img::regex:undef][*::none]' => qq{bar

}, '[img::regex:0][*::none]' => qq{

}, '[img::regex:1][*::none]' => qq{bar

}, '[img::regex:string][*::none]' => qq{

}, '[img::regex:regex][*::none]' => qq{

}, '[img::regex:sub][*::none]' => qq{${id_iat}

}, '[img::sub:undef][*::none]' => qq{bar

}, '[img::sub:0][*::none]' => qq{

}, '[img::sub:1][*::none]' => qq{bar

}, '[img::sub:string][*::none]' => qq{

}, '[img::sub:regex][*::none]' => qq{

}, '[img::sub:sub][*::none]' => qq{${id_iat}

}, '[img::undef:undef][*::undef:undef]' => qq{bar

}, '[img::undef:undef][*::undef:0]' => qq{

}, '[img::undef:undef][*::undef:1]' => qq{bar

}, '[img::undef:undef][*::undef:string]' => qq{

}, '[img::undef:undef][*::undef:regex]' => qq{

}, '[img::undef:undef][*::undef:sub]' => qq{${dd_iat}

}, '[img::undef:undef][*::0:undef]' => qq{bar

}, '[img::undef:undef][*::0:0]' => qq{

}, '[img::undef:undef][*::0:1]' => qq{bar

}, '[img::undef:undef][*::0:string]' => qq{

}, '[img::undef:undef][*::0:regex]' => qq{

}, '[img::undef:undef][*::0:sub]' => qq{${dd_iat}

}, '[img::undef:undef][*::1:undef]' => qq{bar

}, '[img::undef:undef][*::1:0]' => qq{

}, '[img::undef:undef][*::1:1]' => qq{bar

}, '[img::undef:undef][*::1:string]' => qq{

}, '[img::undef:undef][*::1:regex]' => qq{

}, '[img::undef:undef][*::1:sub]' => qq{${dd_iat}

}, '[img::undef:undef][*::string:undef]' => qq{bar

}, '[img::undef:undef][*::string:0]' => qq{

}, '[img::undef:undef][*::string:1]' => qq{bar

}, '[img::undef:undef][*::string:string]' => qq{

}, '[img::undef:undef][*::string:regex]' => qq{

}, '[img::undef:undef][*::string:sub]' => qq{${dd_iat}

}, '[img::undef:undef][*::regex:undef]' => qq{bar

}, '[img::undef:undef][*::regex:0]' => qq{

}, '[img::undef:undef][*::regex:1]' => qq{bar

}, '[img::undef:undef][*::regex:string]' => qq{

}, '[img::undef:undef][*::regex:regex]' => qq{

}, '[img::undef:undef][*::regex:sub]' => qq{${dd_iat}

}, '[img::undef:undef][*::sub:undef]' => qq{bar

}, '[img::undef:undef][*::sub:0]' => qq{

}, '[img::undef:undef][*::sub:1]' => qq{bar

}, '[img::undef:undef][*::sub:string]' => qq{

}, '[img::undef:undef][*::sub:regex]' => qq{

}, '[img::undef:undef][*::sub:sub]' => qq{${dd_iat}

}, '[img::undef:0][*::undef:undef]' => qq{

}, '[img::undef:0][*::undef:0]' => qq{

}, '[img::undef:0][*::undef:1]' => qq{

}, '[img::undef:0][*::undef:string]' => qq{

}, '[img::undef:0][*::undef:regex]' => qq{

}, '[img::undef:0][*::undef:sub]' => qq{

}, '[img::undef:0][*::0:undef]' => qq{

}, '[img::undef:0][*::0:0]' => qq{

}, '[img::undef:0][*::0:1]' => qq{

}, '[img::undef:0][*::0:string]' => qq{

}, '[img::undef:0][*::0:regex]' => qq{

}, '[img::undef:0][*::0:sub]' => qq{

}, '[img::undef:0][*::1:undef]' => qq{

}, '[img::undef:0][*::1:0]' => qq{

}, '[img::undef:0][*::1:1]' => qq{

}, '[img::undef:0][*::1:string]' => qq{

}, '[img::undef:0][*::1:regex]' => qq{

}, '[img::undef:0][*::1:sub]' => qq{

}, '[img::undef:0][*::string:undef]' => qq{

}, '[img::undef:0][*::string:0]' => qq{

}, '[img::undef:0][*::string:1]' => qq{

}, '[img::undef:0][*::string:string]' => qq{

}, '[img::undef:0][*::string:regex]' => qq{

}, '[img::undef:0][*::string:sub]' => qq{

}, '[img::undef:0][*::regex:undef]' => qq{

}, '[img::undef:0][*::regex:0]' => qq{

}, '[img::undef:0][*::regex:1]' => qq{

}, '[img::undef:0][*::regex:string]' => qq{

}, '[img::undef:0][*::regex:regex]' => qq{

}, '[img::undef:0][*::regex:sub]' => qq{

}, '[img::undef:0][*::sub:undef]' => qq{

}, '[img::undef:0][*::sub:0]' => qq{

}, '[img::undef:0][*::sub:1]' => qq{

}, '[img::undef:0][*::sub:string]' => qq{

}, '[img::undef:0][*::sub:regex]' => qq{

}, '[img::undef:0][*::sub:sub]' => qq{

}, '[img::undef:1][*::undef:undef]' => qq{bar

}, '[img::undef:1][*::undef:0]' => qq{bar

}, '[img::undef:1][*::undef:1]' => qq{bar

}, '[img::undef:1][*::undef:string]' => qq{bar

}, '[img::undef:1][*::undef:regex]' => qq{bar

}, '[img::undef:1][*::undef:sub]' => qq{bar

}, '[img::undef:1][*::0:undef]' => qq{bar

}, '[img::undef:1][*::0:0]' => qq{bar

}, '[img::undef:1][*::0:1]' => qq{bar

}, '[img::undef:1][*::0:string]' => qq{bar

}, '[img::undef:1][*::0:regex]' => qq{bar

}, '[img::undef:1][*::0:sub]' => qq{bar

}, '[img::undef:1][*::1:undef]' => qq{bar

}, '[img::undef:1][*::1:0]' => qq{bar

}, '[img::undef:1][*::1:1]' => qq{bar

}, '[img::undef:1][*::1:string]' => qq{bar

}, '[img::undef:1][*::1:regex]' => qq{bar

}, '[img::undef:1][*::1:sub]' => qq{bar

}, '[img::undef:1][*::string:undef]' => qq{bar

}, '[img::undef:1][*::string:0]' => qq{bar

}, '[img::undef:1][*::string:1]' => qq{bar

}, '[img::undef:1][*::string:string]' => qq{bar

}, '[img::undef:1][*::string:regex]' => qq{bar

}, '[img::undef:1][*::string:sub]' => qq{bar

}, '[img::undef:1][*::regex:undef]' => qq{bar

}, '[img::undef:1][*::regex:0]' => qq{bar

}, '[img::undef:1][*::regex:1]' => qq{bar

}, '[img::undef:1][*::regex:string]' => qq{bar

}, '[img::undef:1][*::regex:regex]' => qq{bar

}, '[img::undef:1][*::regex:sub]' => qq{bar

}, '[img::undef:1][*::sub:undef]' => qq{bar

}, '[img::undef:1][*::sub:0]' => qq{bar

}, '[img::undef:1][*::sub:1]' => qq{bar

}, '[img::undef:1][*::sub:string]' => qq{bar

}, '[img::undef:1][*::sub:regex]' => qq{bar

}, '[img::undef:1][*::sub:sub]' => qq{bar

}, '[img::undef:string][*::undef:undef]' => qq{

}, '[img::undef:string][*::undef:0]' => qq{

}, '[img::undef:string][*::undef:1]' => qq{

}, '[img::undef:string][*::undef:string]' => qq{

}, '[img::undef:string][*::undef:regex]' => qq{

}, '[img::undef:string][*::undef:sub]' => qq{

}, '[img::undef:string][*::0:undef]' => qq{

}, '[img::undef:string][*::0:0]' => qq{

}, '[img::undef:string][*::0:1]' => qq{

}, '[img::undef:string][*::0:string]' => qq{

}, '[img::undef:string][*::0:regex]' => qq{

}, '[img::undef:string][*::0:sub]' => qq{

}, '[img::undef:string][*::1:undef]' => qq{

}, '[img::undef:string][*::1:0]' => qq{

}, '[img::undef:string][*::1:1]' => qq{

}, '[img::undef:string][*::1:string]' => qq{

}, '[img::undef:string][*::1:regex]' => qq{

}, '[img::undef:string][*::1:sub]' => qq{

}, '[img::undef:string][*::string:undef]' => qq{

}, '[img::undef:string][*::string:0]' => qq{

}, '[img::undef:string][*::string:1]' => qq{

}, '[img::undef:string][*::string:string]' => qq{

}, '[img::undef:string][*::string:regex]' => qq{

}, '[img::undef:string][*::string:sub]' => qq{

}, '[img::undef:string][*::regex:undef]' => qq{

}, '[img::undef:string][*::regex:0]' => qq{

}, '[img::undef:string][*::regex:1]' => qq{

}, '[img::undef:string][*::regex:string]' => qq{

}, '[img::undef:string][*::regex:regex]' => qq{

}, '[img::undef:string][*::regex:sub]' => qq{

}, '[img::undef:string][*::sub:undef]' => qq{

}, '[img::undef:string][*::sub:0]' => qq{

}, '[img::undef:string][*::sub:1]' => qq{

}, '[img::undef:string][*::sub:string]' => qq{

}, '[img::undef:string][*::sub:regex]' => qq{

}, '[img::undef:string][*::sub:sub]' => qq{

}, '[img::undef:regex][*::undef:undef]' => qq{

}, '[img::undef:regex][*::undef:0]' => qq{

}, '[img::undef:regex][*::undef:1]' => qq{

}, '[img::undef:regex][*::undef:string]' => qq{

}, '[img::undef:regex][*::undef:regex]' => qq{

}, '[img::undef:regex][*::undef:sub]' => qq{

}, '[img::undef:regex][*::0:undef]' => qq{

}, '[img::undef:regex][*::0:0]' => qq{

}, '[img::undef:regex][*::0:1]' => qq{

}, '[img::undef:regex][*::0:string]' => qq{

}, '[img::undef:regex][*::0:regex]' => qq{

}, '[img::undef:regex][*::0:sub]' => qq{

}, '[img::undef:regex][*::1:undef]' => qq{

}, '[img::undef:regex][*::1:0]' => qq{

}, '[img::undef:regex][*::1:1]' => qq{

}, '[img::undef:regex][*::1:string]' => qq{

}, '[img::undef:regex][*::1:regex]' => qq{

}, '[img::undef:regex][*::1:sub]' => qq{

}, '[img::undef:regex][*::string:undef]' => qq{

}, '[img::undef:regex][*::string:0]' => qq{

}, '[img::undef:regex][*::string:1]' => qq{

}, '[img::undef:regex][*::string:string]' => qq{

}, '[img::undef:regex][*::string:regex]' => qq{

}, '[img::undef:regex][*::string:sub]' => qq{

}, '[img::undef:regex][*::regex:undef]' => qq{

}, '[img::undef:regex][*::regex:0]' => qq{

}, '[img::undef:regex][*::regex:1]' => qq{

}, '[img::undef:regex][*::regex:string]' => qq{

}, '[img::undef:regex][*::regex:regex]' => qq{

}, '[img::undef:regex][*::regex:sub]' => qq{

}, '[img::undef:regex][*::sub:undef]' => qq{

}, '[img::undef:regex][*::sub:0]' => qq{

}, '[img::undef:regex][*::sub:1]' => qq{

}, '[img::undef:regex][*::sub:string]' => qq{

}, '[img::undef:regex][*::sub:regex]' => qq{

}, '[img::undef:regex][*::sub:sub]' => qq{

}, '[img::undef:sub][*::undef:undef]' => qq{${id_iat}

}, '[img::undef:sub][*::undef:0]' => qq{${id_iat}

}, '[img::undef:sub][*::undef:1]' => qq{${id_iat}

}, '[img::undef:sub][*::undef:string]' => qq{${id_iat}

}, '[img::undef:sub][*::undef:regex]' => qq{${id_iat}

}, '[img::undef:sub][*::undef:sub]' => qq{${id_iat}

}, '[img::undef:sub][*::0:undef]' => qq{${id_iat}

}, '[img::undef:sub][*::0:0]' => qq{${id_iat}

}, '[img::undef:sub][*::0:1]' => qq{${id_iat}

}, '[img::undef:sub][*::0:string]' => qq{${id_iat}

}, '[img::undef:sub][*::0:regex]' => qq{${id_iat}

}, '[img::undef:sub][*::0:sub]' => qq{${id_iat}

}, '[img::undef:sub][*::1:undef]' => qq{${id_iat}

}, '[img::undef:sub][*::1:0]' => qq{${id_iat}

}, '[img::undef:sub][*::1:1]' => qq{${id_iat}

}, '[img::undef:sub][*::1:string]' => qq{${id_iat}

}, '[img::undef:sub][*::1:regex]' => qq{${id_iat}

}, '[img::undef:sub][*::1:sub]' => qq{${id_iat}

}, '[img::undef:sub][*::string:undef]' => qq{${id_iat}

}, '[img::undef:sub][*::string:0]' => qq{${id_iat}

}, '[img::undef:sub][*::string:1]' => qq{${id_iat}

}, '[img::undef:sub][*::string:string]' => qq{${id_iat}

}, '[img::undef:sub][*::string:regex]' => qq{${id_iat}

}, '[img::undef:sub][*::string:sub]' => qq{${id_iat}

}, '[img::undef:sub][*::regex:undef]' => qq{${id_iat}

}, '[img::undef:sub][*::regex:0]' => qq{${id_iat}

}, '[img::undef:sub][*::regex:1]' => qq{${id_iat}

}, '[img::undef:sub][*::regex:string]' => qq{${id_iat}

}, '[img::undef:sub][*::regex:regex]' => qq{${id_iat}

}, '[img::undef:sub][*::regex:sub]' => qq{${id_iat}

}, '[img::undef:sub][*::sub:undef]' => qq{${id_iat}

}, '[img::undef:sub][*::sub:0]' => qq{${id_iat}

}, '[img::undef:sub][*::sub:1]' => qq{${id_iat}

}, '[img::undef:sub][*::sub:string]' => qq{${id_iat}

}, '[img::undef:sub][*::sub:regex]' => qq{${id_iat}

}, '[img::undef:sub][*::sub:sub]' => qq{${id_iat}

}, '[img::0:undef][*::undef:undef]' => qq{bar

}, '[img::0:undef][*::undef:0]' => qq{

}, '[img::0:undef][*::undef:1]' => qq{bar

}, '[img::0:undef][*::undef:string]' => qq{

}, '[img::0:undef][*::undef:regex]' => qq{

}, '[img::0:undef][*::undef:sub]' => qq{${dd_iat}

}, '[img::0:undef][*::0:undef]' => qq{bar

}, '[img::0:undef][*::0:0]' => qq{

}, '[img::0:undef][*::0:1]' => qq{bar

}, '[img::0:undef][*::0:string]' => qq{

}, '[img::0:undef][*::0:regex]' => qq{

}, '[img::0:undef][*::0:sub]' => qq{${dd_iat}

}, '[img::0:undef][*::1:undef]' => qq{bar

}, '[img::0:undef][*::1:0]' => qq{

}, '[img::0:undef][*::1:1]' => qq{bar

}, '[img::0:undef][*::1:string]' => qq{

}, '[img::0:undef][*::1:regex]' => qq{

}, '[img::0:undef][*::1:sub]' => qq{${dd_iat}

}, '[img::0:undef][*::string:undef]' => qq{bar

}, '[img::0:undef][*::string:0]' => qq{

}, '[img::0:undef][*::string:1]' => qq{bar

}, '[img::0:undef][*::string:string]' => qq{

}, '[img::0:undef][*::string:regex]' => qq{

}, '[img::0:undef][*::string:sub]' => qq{${dd_iat}

}, '[img::0:undef][*::regex:undef]' => qq{bar

}, '[img::0:undef][*::regex:0]' => qq{

}, '[img::0:undef][*::regex:1]' => qq{bar

}, '[img::0:undef][*::regex:string]' => qq{

}, '[img::0:undef][*::regex:regex]' => qq{

}, '[img::0:undef][*::regex:sub]' => qq{${dd_iat}

}, '[img::0:undef][*::sub:undef]' => qq{bar

}, '[img::0:undef][*::sub:0]' => qq{

}, '[img::0:undef][*::sub:1]' => qq{bar

}, '[img::0:undef][*::sub:string]' => qq{

}, '[img::0:undef][*::sub:regex]' => qq{

}, '[img::0:undef][*::sub:sub]' => qq{${dd_iat}

}, '[img::0:0][*::undef:undef]' => qq{

}, '[img::0:0][*::undef:0]' => qq{

}, '[img::0:0][*::undef:1]' => qq{

}, '[img::0:0][*::undef:string]' => qq{

}, '[img::0:0][*::undef:regex]' => qq{

}, '[img::0:0][*::undef:sub]' => qq{

}, '[img::0:0][*::0:undef]' => qq{

}, '[img::0:0][*::0:0]' => qq{

}, '[img::0:0][*::0:1]' => qq{

}, '[img::0:0][*::0:string]' => qq{

}, '[img::0:0][*::0:regex]' => qq{

}, '[img::0:0][*::0:sub]' => qq{

}, '[img::0:0][*::1:undef]' => qq{

}, '[img::0:0][*::1:0]' => qq{

}, '[img::0:0][*::1:1]' => qq{

}, '[img::0:0][*::1:string]' => qq{

}, '[img::0:0][*::1:regex]' => qq{

}, '[img::0:0][*::1:sub]' => qq{

}, '[img::0:0][*::string:undef]' => qq{

}, '[img::0:0][*::string:0]' => qq{

}, '[img::0:0][*::string:1]' => qq{

}, '[img::0:0][*::string:string]' => qq{

}, '[img::0:0][*::string:regex]' => qq{

}, '[img::0:0][*::string:sub]' => qq{

}, '[img::0:0][*::regex:undef]' => qq{

}, '[img::0:0][*::regex:0]' => qq{

}, '[img::0:0][*::regex:1]' => qq{

}, '[img::0:0][*::regex:string]' => qq{

}, '[img::0:0][*::regex:regex]' => qq{

}, '[img::0:0][*::regex:sub]' => qq{

}, '[img::0:0][*::sub:undef]' => qq{

}, '[img::0:0][*::sub:0]' => qq{

}, '[img::0:0][*::sub:1]' => qq{

}, '[img::0:0][*::sub:string]' => qq{

}, '[img::0:0][*::sub:regex]' => qq{

}, '[img::0:0][*::sub:sub]' => qq{

}, '[img::0:1][*::undef:undef]' => qq{bar

}, '[img::0:1][*::undef:0]' => qq{bar

}, '[img::0:1][*::undef:1]' => qq{bar

}, '[img::0:1][*::undef:string]' => qq{bar

}, '[img::0:1][*::undef:regex]' => qq{bar

}, '[img::0:1][*::undef:sub]' => qq{bar

}, '[img::0:1][*::0:undef]' => qq{bar

}, '[img::0:1][*::0:0]' => qq{bar

}, '[img::0:1][*::0:1]' => qq{bar

}, '[img::0:1][*::0:string]' => qq{bar

}, '[img::0:1][*::0:regex]' => qq{bar

}, '[img::0:1][*::0:sub]' => qq{bar

}, '[img::0:1][*::1:undef]' => qq{bar

}, '[img::0:1][*::1:0]' => qq{bar

}, '[img::0:1][*::1:1]' => qq{bar

}, '[img::0:1][*::1:string]' => qq{bar

}, '[img::0:1][*::1:regex]' => qq{bar

}, '[img::0:1][*::1:sub]' => qq{bar

}, '[img::0:1][*::string:undef]' => qq{bar

}, '[img::0:1][*::string:0]' => qq{bar

}, '[img::0:1][*::string:1]' => qq{bar

}, '[img::0:1][*::string:string]' => qq{bar

}, '[img::0:1][*::string:regex]' => qq{bar

}, '[img::0:1][*::string:sub]' => qq{bar

}, '[img::0:1][*::regex:undef]' => qq{bar

}, '[img::0:1][*::regex:0]' => qq{bar

}, '[img::0:1][*::regex:1]' => qq{bar

}, '[img::0:1][*::regex:string]' => qq{bar

}, '[img::0:1][*::regex:regex]' => qq{bar

}, '[img::0:1][*::regex:sub]' => qq{bar

}, '[img::0:1][*::sub:undef]' => qq{bar

}, '[img::0:1][*::sub:0]' => qq{bar

}, '[img::0:1][*::sub:1]' => qq{bar

}, '[img::0:1][*::sub:string]' => qq{bar

}, '[img::0:1][*::sub:regex]' => qq{bar

}, '[img::0:1][*::sub:sub]' => qq{bar

}, '[img::0:string][*::undef:undef]' => qq{

}, '[img::0:string][*::undef:0]' => qq{

}, '[img::0:string][*::undef:1]' => qq{

}, '[img::0:string][*::undef:string]' => qq{

}, '[img::0:string][*::undef:regex]' => qq{

}, '[img::0:string][*::undef:sub]' => qq{

}, '[img::0:string][*::0:undef]' => qq{

}, '[img::0:string][*::0:0]' => qq{

}, '[img::0:string][*::0:1]' => qq{

}, '[img::0:string][*::0:string]' => qq{

}, '[img::0:string][*::0:regex]' => qq{

}, '[img::0:string][*::0:sub]' => qq{

}, '[img::0:string][*::1:undef]' => qq{

}, '[img::0:string][*::1:0]' => qq{

}, '[img::0:string][*::1:1]' => qq{

}, '[img::0:string][*::1:string]' => qq{

}, '[img::0:string][*::1:regex]' => qq{

}, '[img::0:string][*::1:sub]' => qq{

}, '[img::0:string][*::string:undef]' => qq{

}, '[img::0:string][*::string:0]' => qq{

}, '[img::0:string][*::string:1]' => qq{

}, '[img::0:string][*::string:string]' => qq{

}, '[img::0:string][*::string:regex]' => qq{

}, '[img::0:string][*::string:sub]' => qq{

}, '[img::0:string][*::regex:undef]' => qq{

}, '[img::0:string][*::regex:0]' => qq{

}, '[img::0:string][*::regex:1]' => qq{

}, '[img::0:string][*::regex:string]' => qq{

}, '[img::0:string][*::regex:regex]' => qq{

}, '[img::0:string][*::regex:sub]' => qq{

}, '[img::0:string][*::sub:undef]' => qq{

}, '[img::0:string][*::sub:0]' => qq{

}, '[img::0:string][*::sub:1]' => qq{

}, '[img::0:string][*::sub:string]' => qq{

}, '[img::0:string][*::sub:regex]' => qq{

}, '[img::0:string][*::sub:sub]' => qq{

}, '[img::0:regex][*::undef:undef]' => qq{

}, '[img::0:regex][*::undef:0]' => qq{

}, '[img::0:regex][*::undef:1]' => qq{

}, '[img::0:regex][*::undef:string]' => qq{

}, '[img::0:regex][*::undef:regex]' => qq{

}, '[img::0:regex][*::undef:sub]' => qq{

}, '[img::0:regex][*::0:undef]' => qq{

}, '[img::0:regex][*::0:0]' => qq{

}, '[img::0:regex][*::0:1]' => qq{

}, '[img::0:regex][*::0:string]' => qq{

}, '[img::0:regex][*::0:regex]' => qq{

}, '[img::0:regex][*::0:sub]' => qq{

}, '[img::0:regex][*::1:undef]' => qq{

}, '[img::0:regex][*::1:0]' => qq{

}, '[img::0:regex][*::1:1]' => qq{

}, '[img::0:regex][*::1:string]' => qq{

}, '[img::0:regex][*::1:regex]' => qq{

}, '[img::0:regex][*::1:sub]' => qq{

}, '[img::0:regex][*::string:undef]' => qq{

}, '[img::0:regex][*::string:0]' => qq{

}, '[img::0:regex][*::string:1]' => qq{

}, '[img::0:regex][*::string:string]' => qq{

}, '[img::0:regex][*::string:regex]' => qq{

}, '[img::0:regex][*::string:sub]' => qq{

}, '[img::0:regex][*::regex:undef]' => qq{

}, '[img::0:regex][*::regex:0]' => qq{

}, '[img::0:regex][*::regex:1]' => qq{

}, '[img::0:regex][*::regex:string]' => qq{

}, '[img::0:regex][*::regex:regex]' => qq{

}, '[img::0:regex][*::regex:sub]' => qq{

}, '[img::0:regex][*::sub:undef]' => qq{

}, '[img::0:regex][*::sub:0]' => qq{

}, '[img::0:regex][*::sub:1]' => qq{

}, '[img::0:regex][*::sub:string]' => qq{

}, '[img::0:regex][*::sub:regex]' => qq{

}, '[img::0:regex][*::sub:sub]' => qq{

}, '[img::0:sub][*::undef:undef]' => qq{${id_iat}

}, '[img::0:sub][*::undef:0]' => qq{${id_iat}

}, '[img::0:sub][*::undef:1]' => qq{${id_iat}

}, '[img::0:sub][*::undef:string]' => qq{${id_iat}

}, '[img::0:sub][*::undef:regex]' => qq{${id_iat}

}, '[img::0:sub][*::undef:sub]' => qq{${id_iat}

}, '[img::0:sub][*::0:undef]' => qq{${id_iat}

}, '[img::0:sub][*::0:0]' => qq{${id_iat}

}, '[img::0:sub][*::0:1]' => qq{${id_iat}

}, '[img::0:sub][*::0:string]' => qq{${id_iat}

}, '[img::0:sub][*::0:regex]' => qq{${id_iat}

}, '[img::0:sub][*::0:sub]' => qq{${id_iat}

}, '[img::0:sub][*::1:undef]' => qq{${id_iat}

}, '[img::0:sub][*::1:0]' => qq{${id_iat}

}, '[img::0:sub][*::1:1]' => qq{${id_iat}

}, '[img::0:sub][*::1:string]' => qq{${id_iat}

}, '[img::0:sub][*::1:regex]' => qq{${id_iat}

}, '[img::0:sub][*::1:sub]' => qq{${id_iat}

}, '[img::0:sub][*::string:undef]' => qq{${id_iat}

}, '[img::0:sub][*::string:0]' => qq{${id_iat}

}, '[img::0:sub][*::string:1]' => qq{${id_iat}

}, '[img::0:sub][*::string:string]' => qq{${id_iat}

}, '[img::0:sub][*::string:regex]' => qq{${id_iat}

}, '[img::0:sub][*::string:sub]' => qq{${id_iat}

}, '[img::0:sub][*::regex:undef]' => qq{${id_iat}

}, '[img::0:sub][*::regex:0]' => qq{${id_iat}

}, '[img::0:sub][*::regex:1]' => qq{${id_iat}

}, '[img::0:sub][*::regex:string]' => qq{${id_iat}

}, '[img::0:sub][*::regex:regex]' => qq{${id_iat}

}, '[img::0:sub][*::regex:sub]' => qq{${id_iat}

}, '[img::0:sub][*::sub:undef]' => qq{${id_iat}

}, '[img::0:sub][*::sub:0]' => qq{${id_iat}

}, '[img::0:sub][*::sub:1]' => qq{${id_iat}

}, '[img::0:sub][*::sub:string]' => qq{${id_iat}

}, '[img::0:sub][*::sub:regex]' => qq{${id_iat}

}, '[img::0:sub][*::sub:sub]' => qq{${id_iat}

}, '[img::1:undef][*::undef:undef]' => qq{bar

}, '[img::1:undef][*::undef:0]' => qq{

}, '[img::1:undef][*::undef:1]' => qq{bar

}, '[img::1:undef][*::undef:string]' => qq{

}, '[img::1:undef][*::undef:regex]' => qq{

}, '[img::1:undef][*::undef:sub]' => qq{${dd_iat}

}, '[img::1:undef][*::0:undef]' => qq{bar

}, '[img::1:undef][*::0:0]' => qq{

}, '[img::1:undef][*::0:1]' => qq{bar

}, '[img::1:undef][*::0:string]' => qq{

}, '[img::1:undef][*::0:regex]' => qq{

}, '[img::1:undef][*::0:sub]' => qq{${dd_iat}

}, '[img::1:undef][*::1:undef]' => qq{bar

}, '[img::1:undef][*::1:0]' => qq{

}, '[img::1:undef][*::1:1]' => qq{bar

}, '[img::1:undef][*::1:string]' => qq{

}, '[img::1:undef][*::1:regex]' => qq{

}, '[img::1:undef][*::1:sub]' => qq{${dd_iat}

}, '[img::1:undef][*::string:undef]' => qq{bar

}, '[img::1:undef][*::string:0]' => qq{

}, '[img::1:undef][*::string:1]' => qq{bar

}, '[img::1:undef][*::string:string]' => qq{

}, '[img::1:undef][*::string:regex]' => qq{

}, '[img::1:undef][*::string:sub]' => qq{${dd_iat}

}, '[img::1:undef][*::regex:undef]' => qq{bar

}, '[img::1:undef][*::regex:0]' => qq{

}, '[img::1:undef][*::regex:1]' => qq{bar

}, '[img::1:undef][*::regex:string]' => qq{

}, '[img::1:undef][*::regex:regex]' => qq{

}, '[img::1:undef][*::regex:sub]' => qq{${dd_iat}

}, '[img::1:undef][*::sub:undef]' => qq{bar

}, '[img::1:undef][*::sub:0]' => qq{

}, '[img::1:undef][*::sub:1]' => qq{bar

}, '[img::1:undef][*::sub:string]' => qq{

}, '[img::1:undef][*::sub:regex]' => qq{

}, '[img::1:undef][*::sub:sub]' => qq{${dd_iat}

}, '[img::1:0][*::undef:undef]' => qq{

}, '[img::1:0][*::undef:0]' => qq{

}, '[img::1:0][*::undef:1]' => qq{

}, '[img::1:0][*::undef:string]' => qq{

}, '[img::1:0][*::undef:regex]' => qq{

}, '[img::1:0][*::undef:sub]' => qq{

}, '[img::1:0][*::0:undef]' => qq{

}, '[img::1:0][*::0:0]' => qq{

}, '[img::1:0][*::0:1]' => qq{

}, '[img::1:0][*::0:string]' => qq{

}, '[img::1:0][*::0:regex]' => qq{

}, '[img::1:0][*::0:sub]' => qq{

}, '[img::1:0][*::1:undef]' => qq{

}, '[img::1:0][*::1:0]' => qq{

}, '[img::1:0][*::1:1]' => qq{

}, '[img::1:0][*::1:string]' => qq{

}, '[img::1:0][*::1:regex]' => qq{

}, '[img::1:0][*::1:sub]' => qq{

}, '[img::1:0][*::string:undef]' => qq{

}, '[img::1:0][*::string:0]' => qq{

}, '[img::1:0][*::string:1]' => qq{

}, '[img::1:0][*::string:string]' => qq{

}, '[img::1:0][*::string:regex]' => qq{

}, '[img::1:0][*::string:sub]' => qq{

}, '[img::1:0][*::regex:undef]' => qq{

}, '[img::1:0][*::regex:0]' => qq{

}, '[img::1:0][*::regex:1]' => qq{

}, '[img::1:0][*::regex:string]' => qq{

}, '[img::1:0][*::regex:regex]' => qq{

}, '[img::1:0][*::regex:sub]' => qq{

}, '[img::1:0][*::sub:undef]' => qq{

}, '[img::1:0][*::sub:0]' => qq{

}, '[img::1:0][*::sub:1]' => qq{

}, '[img::1:0][*::sub:string]' => qq{

}, '[img::1:0][*::sub:regex]' => qq{

}, '[img::1:0][*::sub:sub]' => qq{

}, '[img::1:1][*::undef:undef]' => qq{bar

}, '[img::1:1][*::undef:0]' => qq{bar

}, '[img::1:1][*::undef:1]' => qq{bar

}, '[img::1:1][*::undef:string]' => qq{bar

}, '[img::1:1][*::undef:regex]' => qq{bar

}, '[img::1:1][*::undef:sub]' => qq{bar

}, '[img::1:1][*::0:undef]' => qq{bar

}, '[img::1:1][*::0:0]' => qq{bar

}, '[img::1:1][*::0:1]' => qq{bar

}, '[img::1:1][*::0:string]' => qq{bar

}, '[img::1:1][*::0:regex]' => qq{bar

}, '[img::1:1][*::0:sub]' => qq{bar

}, '[img::1:1][*::1:undef]' => qq{bar

}, '[img::1:1][*::1:0]' => qq{bar

}, '[img::1:1][*::1:1]' => qq{bar

}, '[img::1:1][*::1:string]' => qq{bar

}, '[img::1:1][*::1:regex]' => qq{bar

}, '[img::1:1][*::1:sub]' => qq{bar

}, '[img::1:1][*::string:undef]' => qq{bar

}, '[img::1:1][*::string:0]' => qq{bar

}, '[img::1:1][*::string:1]' => qq{bar

}, '[img::1:1][*::string:string]' => qq{bar

}, '[img::1:1][*::string:regex]' => qq{bar

}, '[img::1:1][*::string:sub]' => qq{bar

}, '[img::1:1][*::regex:undef]' => qq{bar

}, '[img::1:1][*::regex:0]' => qq{bar

}, '[img::1:1][*::regex:1]' => qq{bar

}, '[img::1:1][*::regex:string]' => qq{bar

}, '[img::1:1][*::regex:regex]' => qq{bar

}, '[img::1:1][*::regex:sub]' => qq{bar

}, '[img::1:1][*::sub:undef]' => qq{bar

}, '[img::1:1][*::sub:0]' => qq{bar

}, '[img::1:1][*::sub:1]' => qq{bar

}, '[img::1:1][*::sub:string]' => qq{bar

}, '[img::1:1][*::sub:regex]' => qq{bar

}, '[img::1:1][*::sub:sub]' => qq{bar

}, '[img::1:string][*::undef:undef]' => qq{

}, '[img::1:string][*::undef:0]' => qq{

}, '[img::1:string][*::undef:1]' => qq{

}, '[img::1:string][*::undef:string]' => qq{

}, '[img::1:string][*::undef:regex]' => qq{

}, '[img::1:string][*::undef:sub]' => qq{

}, '[img::1:string][*::0:undef]' => qq{

}, '[img::1:string][*::0:0]' => qq{

}, '[img::1:string][*::0:1]' => qq{

}, '[img::1:string][*::0:string]' => qq{

}, '[img::1:string][*::0:regex]' => qq{

}, '[img::1:string][*::0:sub]' => qq{

}, '[img::1:string][*::1:undef]' => qq{

}, '[img::1:string][*::1:0]' => qq{

}, '[img::1:string][*::1:1]' => qq{

}, '[img::1:string][*::1:string]' => qq{

}, '[img::1:string][*::1:regex]' => qq{

}, '[img::1:string][*::1:sub]' => qq{

}, '[img::1:string][*::string:undef]' => qq{

}, '[img::1:string][*::string:0]' => qq{

}, '[img::1:string][*::string:1]' => qq{

}, '[img::1:string][*::string:string]' => qq{

}, '[img::1:string][*::string:regex]' => qq{

}, '[img::1:string][*::string:sub]' => qq{

}, '[img::1:string][*::regex:undef]' => qq{

}, '[img::1:string][*::regex:0]' => qq{

}, '[img::1:string][*::regex:1]' => qq{

}, '[img::1:string][*::regex:string]' => qq{

}, '[img::1:string][*::regex:regex]' => qq{

}, '[img::1:string][*::regex:sub]' => qq{

}, '[img::1:string][*::sub:undef]' => qq{

}, '[img::1:string][*::sub:0]' => qq{

}, '[img::1:string][*::sub:1]' => qq{

}, '[img::1:string][*::sub:string]' => qq{

}, '[img::1:string][*::sub:regex]' => qq{

}, '[img::1:string][*::sub:sub]' => qq{

}, '[img::1:regex][*::undef:undef]' => qq{

}, '[img::1:regex][*::undef:0]' => qq{

}, '[img::1:regex][*::undef:1]' => qq{

}, '[img::1:regex][*::undef:string]' => qq{

}, '[img::1:regex][*::undef:regex]' => qq{

}, '[img::1:regex][*::undef:sub]' => qq{

}, '[img::1:regex][*::0:undef]' => qq{

}, '[img::1:regex][*::0:0]' => qq{

}, '[img::1:regex][*::0:1]' => qq{

}, '[img::1:regex][*::0:string]' => qq{

}, '[img::1:regex][*::0:regex]' => qq{

}, '[img::1:regex][*::0:sub]' => qq{

}, '[img::1:regex][*::1:undef]' => qq{

}, '[img::1:regex][*::1:0]' => qq{

}, '[img::1:regex][*::1:1]' => qq{

}, '[img::1:regex][*::1:string]' => qq{

}, '[img::1:regex][*::1:regex]' => qq{

}, '[img::1:regex][*::1:sub]' => qq{

}, '[img::1:regex][*::string:undef]' => qq{

}, '[img::1:regex][*::string:0]' => qq{

}, '[img::1:regex][*::string:1]' => qq{

}, '[img::1:regex][*::string:string]' => qq{

}, '[img::1:regex][*::string:regex]' => qq{

}, '[img::1:regex][*::string:sub]' => qq{

}, '[img::1:regex][*::regex:undef]' => qq{

}, '[img::1:regex][*::regex:0]' => qq{

}, '[img::1:regex][*::regex:1]' => qq{

}, '[img::1:regex][*::regex:string]' => qq{

}, '[img::1:regex][*::regex:regex]' => qq{

}, '[img::1:regex][*::regex:sub]' => qq{

}, '[img::1:regex][*::sub:undef]' => qq{

}, '[img::1:regex][*::sub:0]' => qq{

}, '[img::1:regex][*::sub:1]' => qq{

}, '[img::1:regex][*::sub:string]' => qq{

}, '[img::1:regex][*::sub:regex]' => qq{

}, '[img::1:regex][*::sub:sub]' => qq{

}, '[img::1:sub][*::undef:undef]' => qq{${id_iat}

}, '[img::1:sub][*::undef:0]' => qq{${id_iat}

}, '[img::1:sub][*::undef:1]' => qq{${id_iat}

}, '[img::1:sub][*::undef:string]' => qq{${id_iat}

}, '[img::1:sub][*::undef:regex]' => qq{${id_iat}

}, '[img::1:sub][*::undef:sub]' => qq{${id_iat}

}, '[img::1:sub][*::0:undef]' => qq{${id_iat}

}, '[img::1:sub][*::0:0]' => qq{${id_iat}

}, '[img::1:sub][*::0:1]' => qq{${id_iat}

}, '[img::1:sub][*::0:string]' => qq{${id_iat}

}, '[img::1:sub][*::0:regex]' => qq{${id_iat}

}, '[img::1:sub][*::0:sub]' => qq{${id_iat}

}, '[img::1:sub][*::1:undef]' => qq{${id_iat}

}, '[img::1:sub][*::1:0]' => qq{${id_iat}

}, '[img::1:sub][*::1:1]' => qq{${id_iat}

}, '[img::1:sub][*::1:string]' => qq{${id_iat}

}, '[img::1:sub][*::1:regex]' => qq{${id_iat}

}, '[img::1:sub][*::1:sub]' => qq{${id_iat}

}, '[img::1:sub][*::string:undef]' => qq{${id_iat}

}, '[img::1:sub][*::string:0]' => qq{${id_iat}

}, '[img::1:sub][*::string:1]' => qq{${id_iat}

}, '[img::1:sub][*::string:string]' => qq{${id_iat}

}, '[img::1:sub][*::string:regex]' => qq{${id_iat}

}, '[img::1:sub][*::string:sub]' => qq{${id_iat}

}, '[img::1:sub][*::regex:undef]' => qq{${id_iat}

}, '[img::1:sub][*::regex:0]' => qq{${id_iat}

}, '[img::1:sub][*::regex:1]' => qq{${id_iat}

}, '[img::1:sub][*::regex:string]' => qq{${id_iat}

}, '[img::1:sub][*::regex:regex]' => qq{${id_iat}

}, '[img::1:sub][*::regex:sub]' => qq{${id_iat}

}, '[img::1:sub][*::sub:undef]' => qq{${id_iat}

}, '[img::1:sub][*::sub:0]' => qq{${id_iat}

}, '[img::1:sub][*::sub:1]' => qq{${id_iat}

}, '[img::1:sub][*::sub:string]' => qq{${id_iat}

}, '[img::1:sub][*::sub:regex]' => qq{${id_iat}

}, '[img::1:sub][*::sub:sub]' => qq{${id_iat}

}, '[img::string:undef][*::undef:undef]' => qq{bar

}, '[img::string:undef][*::undef:0]' => qq{

}, '[img::string:undef][*::undef:1]' => qq{bar

}, '[img::string:undef][*::undef:string]' => qq{

}, '[img::string:undef][*::undef:regex]' => qq{

}, '[img::string:undef][*::undef:sub]' => qq{${dd_iat}

}, '[img::string:undef][*::0:undef]' => qq{bar

}, '[img::string:undef][*::0:0]' => qq{

}, '[img::string:undef][*::0:1]' => qq{bar

}, '[img::string:undef][*::0:string]' => qq{

}, '[img::string:undef][*::0:regex]' => qq{

}, '[img::string:undef][*::0:sub]' => qq{${dd_iat}

}, '[img::string:undef][*::1:undef]' => qq{bar

}, '[img::string:undef][*::1:0]' => qq{

}, '[img::string:undef][*::1:1]' => qq{bar

}, '[img::string:undef][*::1:string]' => qq{

}, '[img::string:undef][*::1:regex]' => qq{

}, '[img::string:undef][*::1:sub]' => qq{${dd_iat}

}, '[img::string:undef][*::string:undef]' => qq{bar

}, '[img::string:undef][*::string:0]' => qq{

}, '[img::string:undef][*::string:1]' => qq{bar

}, '[img::string:undef][*::string:string]' => qq{

}, '[img::string:undef][*::string:regex]' => qq{

}, '[img::string:undef][*::string:sub]' => qq{${dd_iat}

}, '[img::string:undef][*::regex:undef]' => qq{bar

}, '[img::string:undef][*::regex:0]' => qq{

}, '[img::string:undef][*::regex:1]' => qq{bar

}, '[img::string:undef][*::regex:string]' => qq{

}, '[img::string:undef][*::regex:regex]' => qq{

}, '[img::string:undef][*::regex:sub]' => qq{${dd_iat}

}, '[img::string:undef][*::sub:undef]' => qq{bar

}, '[img::string:undef][*::sub:0]' => qq{

}, '[img::string:undef][*::sub:1]' => qq{bar

}, '[img::string:undef][*::sub:string]' => qq{

}, '[img::string:undef][*::sub:regex]' => qq{

}, '[img::string:undef][*::sub:sub]' => qq{${dd_iat}

}, '[img::string:0][*::undef:undef]' => qq{

}, '[img::string:0][*::undef:0]' => qq{

}, '[img::string:0][*::undef:1]' => qq{

}, '[img::string:0][*::undef:string]' => qq{

}, '[img::string:0][*::undef:regex]' => qq{

}, '[img::string:0][*::undef:sub]' => qq{

}, '[img::string:0][*::0:undef]' => qq{

}, '[img::string:0][*::0:0]' => qq{

}, '[img::string:0][*::0:1]' => qq{

}, '[img::string:0][*::0:string]' => qq{

}, '[img::string:0][*::0:regex]' => qq{

}, '[img::string:0][*::0:sub]' => qq{

}, '[img::string:0][*::1:undef]' => qq{

}, '[img::string:0][*::1:0]' => qq{

}, '[img::string:0][*::1:1]' => qq{

}, '[img::string:0][*::1:string]' => qq{

}, '[img::string:0][*::1:regex]' => qq{

}, '[img::string:0][*::1:sub]' => qq{

}, '[img::string:0][*::string:undef]' => qq{

}, '[img::string:0][*::string:0]' => qq{

}, '[img::string:0][*::string:1]' => qq{

}, '[img::string:0][*::string:string]' => qq{

}, '[img::string:0][*::string:regex]' => qq{

}, '[img::string:0][*::string:sub]' => qq{

}, '[img::string:0][*::regex:undef]' => qq{

}, '[img::string:0][*::regex:0]' => qq{

}, '[img::string:0][*::regex:1]' => qq{

}, '[img::string:0][*::regex:string]' => qq{

}, '[img::string:0][*::regex:regex]' => qq{

}, '[img::string:0][*::regex:sub]' => qq{

}, '[img::string:0][*::sub:undef]' => qq{

}, '[img::string:0][*::sub:0]' => qq{

}, '[img::string:0][*::sub:1]' => qq{

}, '[img::string:0][*::sub:string]' => qq{

}, '[img::string:0][*::sub:regex]' => qq{

}, '[img::string:0][*::sub:sub]' => qq{

}, '[img::string:1][*::undef:undef]' => qq{bar

}, '[img::string:1][*::undef:0]' => qq{bar

}, '[img::string:1][*::undef:1]' => qq{bar

}, '[img::string:1][*::undef:string]' => qq{bar

}, '[img::string:1][*::undef:regex]' => qq{bar

}, '[img::string:1][*::undef:sub]' => qq{bar

}, '[img::string:1][*::0:undef]' => qq{bar

}, '[img::string:1][*::0:0]' => qq{bar

}, '[img::string:1][*::0:1]' => qq{bar

}, '[img::string:1][*::0:string]' => qq{bar

}, '[img::string:1][*::0:regex]' => qq{bar

}, '[img::string:1][*::0:sub]' => qq{bar

}, '[img::string:1][*::1:undef]' => qq{bar

}, '[img::string:1][*::1:0]' => qq{bar

}, '[img::string:1][*::1:1]' => qq{bar

}, '[img::string:1][*::1:string]' => qq{bar

}, '[img::string:1][*::1:regex]' => qq{bar

}, '[img::string:1][*::1:sub]' => qq{bar

}, '[img::string:1][*::string:undef]' => qq{bar

}, '[img::string:1][*::string:0]' => qq{bar

}, '[img::string:1][*::string:1]' => qq{bar

}, '[img::string:1][*::string:string]' => qq{bar

}, '[img::string:1][*::string:regex]' => qq{bar

}, '[img::string:1][*::string:sub]' => qq{bar

}, '[img::string:1][*::regex:undef]' => qq{bar

}, '[img::string:1][*::regex:0]' => qq{bar

}, '[img::string:1][*::regex:1]' => qq{bar

}, '[img::string:1][*::regex:string]' => qq{bar

}, '[img::string:1][*::regex:regex]' => qq{bar

}, '[img::string:1][*::regex:sub]' => qq{bar

}, '[img::string:1][*::sub:undef]' => qq{bar

}, '[img::string:1][*::sub:0]' => qq{bar

}, '[img::string:1][*::sub:1]' => qq{bar

}, '[img::string:1][*::sub:string]' => qq{bar

}, '[img::string:1][*::sub:regex]' => qq{bar

}, '[img::string:1][*::sub:sub]' => qq{bar

}, '[img::string:string][*::undef:undef]' => qq{

}, '[img::string:string][*::undef:0]' => qq{

}, '[img::string:string][*::undef:1]' => qq{

}, '[img::string:string][*::undef:string]' => qq{

}, '[img::string:string][*::undef:regex]' => qq{

}, '[img::string:string][*::undef:sub]' => qq{

}, '[img::string:string][*::0:undef]' => qq{

}, '[img::string:string][*::0:0]' => qq{

}, '[img::string:string][*::0:1]' => qq{

}, '[img::string:string][*::0:string]' => qq{

}, '[img::string:string][*::0:regex]' => qq{

}, '[img::string:string][*::0:sub]' => qq{

}, '[img::string:string][*::1:undef]' => qq{

}, '[img::string:string][*::1:0]' => qq{

}, '[img::string:string][*::1:1]' => qq{

}, '[img::string:string][*::1:string]' => qq{

}, '[img::string:string][*::1:regex]' => qq{

}, '[img::string:string][*::1:sub]' => qq{

}, '[img::string:string][*::string:undef]' => qq{

}, '[img::string:string][*::string:0]' => qq{

}, '[img::string:string][*::string:1]' => qq{

}, '[img::string:string][*::string:string]' => qq{

}, '[img::string:string][*::string:regex]' => qq{

}, '[img::string:string][*::string:sub]' => qq{

}, '[img::string:string][*::regex:undef]' => qq{

}, '[img::string:string][*::regex:0]' => qq{

}, '[img::string:string][*::regex:1]' => qq{

}, '[img::string:string][*::regex:string]' => qq{

}, '[img::string:string][*::regex:regex]' => qq{

}, '[img::string:string][*::regex:sub]' => qq{

}, '[img::string:string][*::sub:undef]' => qq{

}, '[img::string:string][*::sub:0]' => qq{

}, '[img::string:string][*::sub:1]' => qq{

}, '[img::string:string][*::sub:string]' => qq{

}, '[img::string:string][*::sub:regex]' => qq{

}, '[img::string:string][*::sub:sub]' => qq{

}, '[img::string:regex][*::undef:undef]' => qq{

}, '[img::string:regex][*::undef:0]' => qq{

}, '[img::string:regex][*::undef:1]' => qq{

}, '[img::string:regex][*::undef:string]' => qq{

}, '[img::string:regex][*::undef:regex]' => qq{

}, '[img::string:regex][*::undef:sub]' => qq{

}, '[img::string:regex][*::0:undef]' => qq{

}, '[img::string:regex][*::0:0]' => qq{

}, '[img::string:regex][*::0:1]' => qq{

}, '[img::string:regex][*::0:string]' => qq{

}, '[img::string:regex][*::0:regex]' => qq{

}, '[img::string:regex][*::0:sub]' => qq{

}, '[img::string:regex][*::1:undef]' => qq{

}, '[img::string:regex][*::1:0]' => qq{

}, '[img::string:regex][*::1:1]' => qq{

}, '[img::string:regex][*::1:string]' => qq{

}, '[img::string:regex][*::1:regex]' => qq{

}, '[img::string:regex][*::1:sub]' => qq{

}, '[img::string:regex][*::string:undef]' => qq{

}, '[img::string:regex][*::string:0]' => qq{

}, '[img::string:regex][*::string:1]' => qq{

}, '[img::string:regex][*::string:string]' => qq{

}, '[img::string:regex][*::string:regex]' => qq{

}, '[img::string:regex][*::string:sub]' => qq{

}, '[img::string:regex][*::regex:undef]' => qq{

}, '[img::string:regex][*::regex:0]' => qq{

}, '[img::string:regex][*::regex:1]' => qq{

}, '[img::string:regex][*::regex:string]' => qq{

}, '[img::string:regex][*::regex:regex]' => qq{

}, '[img::string:regex][*::regex:sub]' => qq{

}, '[img::string:regex][*::sub:undef]' => qq{

}, '[img::string:regex][*::sub:0]' => qq{

}, '[img::string:regex][*::sub:1]' => qq{

}, '[img::string:regex][*::sub:string]' => qq{

}, '[img::string:regex][*::sub:regex]' => qq{

}, '[img::string:regex][*::sub:sub]' => qq{

}, '[img::string:sub][*::undef:undef]' => qq{${id_iat}

}, '[img::string:sub][*::undef:0]' => qq{${id_iat}

}, '[img::string:sub][*::undef:1]' => qq{${id_iat}

}, '[img::string:sub][*::undef:string]' => qq{${id_iat}

}, '[img::string:sub][*::undef:regex]' => qq{${id_iat}

}, '[img::string:sub][*::undef:sub]' => qq{${id_iat}

}, '[img::string:sub][*::0:undef]' => qq{${id_iat}

}, '[img::string:sub][*::0:0]' => qq{${id_iat}

}, '[img::string:sub][*::0:1]' => qq{${id_iat}

}, '[img::string:sub][*::0:string]' => qq{${id_iat}

}, '[img::string:sub][*::0:regex]' => qq{${id_iat}

}, '[img::string:sub][*::0:sub]' => qq{${id_iat}

}, '[img::string:sub][*::1:undef]' => qq{${id_iat}

}, '[img::string:sub][*::1:0]' => qq{${id_iat}

}, '[img::string:sub][*::1:1]' => qq{${id_iat}

}, '[img::string:sub][*::1:string]' => qq{${id_iat}

}, '[img::string:sub][*::1:regex]' => qq{${id_iat}

}, '[img::string:sub][*::1:sub]' => qq{${id_iat}

}, '[img::string:sub][*::string:undef]' => qq{${id_iat}

}, '[img::string:sub][*::string:0]' => qq{${id_iat}

}, '[img::string:sub][*::string:1]' => qq{${id_iat}

}, '[img::string:sub][*::string:string]' => qq{${id_iat}

}, '[img::string:sub][*::string:regex]' => qq{${id_iat}

}, '[img::string:sub][*::string:sub]' => qq{${id_iat}

}, '[img::string:sub][*::regex:undef]' => qq{${id_iat}

}, '[img::string:sub][*::regex:0]' => qq{${id_iat}

}, '[img::string:sub][*::regex:1]' => qq{${id_iat}

}, '[img::string:sub][*::regex:string]' => qq{${id_iat}

}, '[img::string:sub][*::regex:regex]' => qq{${id_iat}

}, '[img::string:sub][*::regex:sub]' => qq{${id_iat}

}, '[img::string:sub][*::sub:undef]' => qq{${id_iat}

}, '[img::string:sub][*::sub:0]' => qq{${id_iat}

}, '[img::string:sub][*::sub:1]' => qq{${id_iat}

}, '[img::string:sub][*::sub:string]' => qq{${id_iat}

}, '[img::string:sub][*::sub:regex]' => qq{${id_iat}

}, '[img::string:sub][*::sub:sub]' => qq{${id_iat}

}, '[img::regex:undef][*::undef:undef]' => qq{bar

}, '[img::regex:undef][*::undef:0]' => qq{

}, '[img::regex:undef][*::undef:1]' => qq{bar

}, '[img::regex:undef][*::undef:string]' => qq{

}, '[img::regex:undef][*::undef:regex]' => qq{

}, '[img::regex:undef][*::undef:sub]' => qq{${dd_iat}

}, '[img::regex:undef][*::0:undef]' => qq{bar

}, '[img::regex:undef][*::0:0]' => qq{

}, '[img::regex:undef][*::0:1]' => qq{bar

}, '[img::regex:undef][*::0:string]' => qq{

}, '[img::regex:undef][*::0:regex]' => qq{

}, '[img::regex:undef][*::0:sub]' => qq{${dd_iat}

}, '[img::regex:undef][*::1:undef]' => qq{bar

}, '[img::regex:undef][*::1:0]' => qq{

}, '[img::regex:undef][*::1:1]' => qq{bar

}, '[img::regex:undef][*::1:string]' => qq{

}, '[img::regex:undef][*::1:regex]' => qq{

}, '[img::regex:undef][*::1:sub]' => qq{${dd_iat}

}, '[img::regex:undef][*::string:undef]' => qq{bar

}, '[img::regex:undef][*::string:0]' => qq{

}, '[img::regex:undef][*::string:1]' => qq{bar

}, '[img::regex:undef][*::string:string]' => qq{

}, '[img::regex:undef][*::string:regex]' => qq{

}, '[img::regex:undef][*::string:sub]' => qq{${dd_iat}

}, '[img::regex:undef][*::regex:undef]' => qq{bar

}, '[img::regex:undef][*::regex:0]' => qq{

}, '[img::regex:undef][*::regex:1]' => qq{bar

}, '[img::regex:undef][*::regex:string]' => qq{

}, '[img::regex:undef][*::regex:regex]' => qq{

}, '[img::regex:undef][*::regex:sub]' => qq{${dd_iat}

}, '[img::regex:undef][*::sub:undef]' => qq{bar

}, '[img::regex:undef][*::sub:0]' => qq{

}, '[img::regex:undef][*::sub:1]' => qq{bar

}, '[img::regex:undef][*::sub:string]' => qq{

}, '[img::regex:undef][*::sub:regex]' => qq{

}, '[img::regex:undef][*::sub:sub]' => qq{${dd_iat}

}, '[img::regex:0][*::undef:undef]' => qq{

}, '[img::regex:0][*::undef:0]' => qq{

}, '[img::regex:0][*::undef:1]' => qq{

}, '[img::regex:0][*::undef:string]' => qq{

}, '[img::regex:0][*::undef:regex]' => qq{

}, '[img::regex:0][*::undef:sub]' => qq{

}, '[img::regex:0][*::0:undef]' => qq{

}, '[img::regex:0][*::0:0]' => qq{

}, '[img::regex:0][*::0:1]' => qq{

}, '[img::regex:0][*::0:string]' => qq{

}, '[img::regex:0][*::0:regex]' => qq{

}, '[img::regex:0][*::0:sub]' => qq{

}, '[img::regex:0][*::1:undef]' => qq{

}, '[img::regex:0][*::1:0]' => qq{

}, '[img::regex:0][*::1:1]' => qq{

}, '[img::regex:0][*::1:string]' => qq{

}, '[img::regex:0][*::1:regex]' => qq{

}, '[img::regex:0][*::1:sub]' => qq{

}, '[img::regex:0][*::string:undef]' => qq{

}, '[img::regex:0][*::string:0]' => qq{

}, '[img::regex:0][*::string:1]' => qq{

}, '[img::regex:0][*::string:string]' => qq{

}, '[img::regex:0][*::string:regex]' => qq{

}, '[img::regex:0][*::string:sub]' => qq{

}, '[img::regex:0][*::regex:undef]' => qq{

}, '[img::regex:0][*::regex:0]' => qq{

}, '[img::regex:0][*::regex:1]' => qq{

}, '[img::regex:0][*::regex:string]' => qq{

}, '[img::regex:0][*::regex:regex]' => qq{

}, '[img::regex:0][*::regex:sub]' => qq{

}, '[img::regex:0][*::sub:undef]' => qq{

}, '[img::regex:0][*::sub:0]' => qq{

}, '[img::regex:0][*::sub:1]' => qq{

}, '[img::regex:0][*::sub:string]' => qq{

}, '[img::regex:0][*::sub:regex]' => qq{

}, '[img::regex:0][*::sub:sub]' => qq{

}, '[img::regex:1][*::undef:undef]' => qq{bar

}, '[img::regex:1][*::undef:0]' => qq{bar

}, '[img::regex:1][*::undef:1]' => qq{bar

}, '[img::regex:1][*::undef:string]' => qq{bar

}, '[img::regex:1][*::undef:regex]' => qq{bar

}, '[img::regex:1][*::undef:sub]' => qq{bar

}, '[img::regex:1][*::0:undef]' => qq{bar

}, '[img::regex:1][*::0:0]' => qq{bar

}, '[img::regex:1][*::0:1]' => qq{bar

}, '[img::regex:1][*::0:string]' => qq{bar

}, '[img::regex:1][*::0:regex]' => qq{bar

}, '[img::regex:1][*::0:sub]' => qq{bar

}, '[img::regex:1][*::1:undef]' => qq{bar

}, '[img::regex:1][*::1:0]' => qq{bar

}, '[img::regex:1][*::1:1]' => qq{bar

}, '[img::regex:1][*::1:string]' => qq{bar

}, '[img::regex:1][*::1:regex]' => qq{bar

}, '[img::regex:1][*::1:sub]' => qq{bar

}, '[img::regex:1][*::string:undef]' => qq{bar

}, '[img::regex:1][*::string:0]' => qq{bar

}, '[img::regex:1][*::string:1]' => qq{bar

}, '[img::regex:1][*::string:string]' => qq{bar

}, '[img::regex:1][*::string:regex]' => qq{bar

}, '[img::regex:1][*::string:sub]' => qq{bar

}, '[img::regex:1][*::regex:undef]' => qq{bar

}, '[img::regex:1][*::regex:0]' => qq{bar

}, '[img::regex:1][*::regex:1]' => qq{bar

}, '[img::regex:1][*::regex:string]' => qq{bar

}, '[img::regex:1][*::regex:regex]' => qq{bar

}, '[img::regex:1][*::regex:sub]' => qq{bar

}, '[img::regex:1][*::sub:undef]' => qq{bar

}, '[img::regex:1][*::sub:0]' => qq{bar

}, '[img::regex:1][*::sub:1]' => qq{bar

}, '[img::regex:1][*::sub:string]' => qq{bar

}, '[img::regex:1][*::sub:regex]' => qq{bar

}, '[img::regex:1][*::sub:sub]' => qq{bar

}, '[img::regex:string][*::undef:undef]' => qq{

}, '[img::regex:string][*::undef:0]' => qq{

}, '[img::regex:string][*::undef:1]' => qq{

}, '[img::regex:string][*::undef:string]' => qq{

}, '[img::regex:string][*::undef:regex]' => qq{

}, '[img::regex:string][*::undef:sub]' => qq{

}, '[img::regex:string][*::0:undef]' => qq{

}, '[img::regex:string][*::0:0]' => qq{

}, '[img::regex:string][*::0:1]' => qq{

}, '[img::regex:string][*::0:string]' => qq{

}, '[img::regex:string][*::0:regex]' => qq{

}, '[img::regex:string][*::0:sub]' => qq{

}, '[img::regex:string][*::1:undef]' => qq{

}, '[img::regex:string][*::1:0]' => qq{

}, '[img::regex:string][*::1:1]' => qq{

}, '[img::regex:string][*::1:string]' => qq{

}, '[img::regex:string][*::1:regex]' => qq{

}, '[img::regex:string][*::1:sub]' => qq{

}, '[img::regex:string][*::string:undef]' => qq{

}, '[img::regex:string][*::string:0]' => qq{

}, '[img::regex:string][*::string:1]' => qq{

}, '[img::regex:string][*::string:string]' => qq{

}, '[img::regex:string][*::string:regex]' => qq{

}, '[img::regex:string][*::string:sub]' => qq{

}, '[img::regex:string][*::regex:undef]' => qq{

}, '[img::regex:string][*::regex:0]' => qq{

}, '[img::regex:string][*::regex:1]' => qq{

}, '[img::regex:string][*::regex:string]' => qq{

}, '[img::regex:string][*::regex:regex]' => qq{

}, '[img::regex:string][*::regex:sub]' => qq{

}, '[img::regex:string][*::sub:undef]' => qq{

}, '[img::regex:string][*::sub:0]' => qq{

}, '[img::regex:string][*::sub:1]' => qq{

}, '[img::regex:string][*::sub:string]' => qq{

}, '[img::regex:string][*::sub:regex]' => qq{

}, '[img::regex:string][*::sub:sub]' => qq{

}, '[img::regex:regex][*::undef:undef]' => qq{

}, '[img::regex:regex][*::undef:0]' => qq{

}, '[img::regex:regex][*::undef:1]' => qq{

}, '[img::regex:regex][*::undef:string]' => qq{

}, '[img::regex:regex][*::undef:regex]' => qq{

}, '[img::regex:regex][*::undef:sub]' => qq{

}, '[img::regex:regex][*::0:undef]' => qq{

}, '[img::regex:regex][*::0:0]' => qq{

}, '[img::regex:regex][*::0:1]' => qq{

}, '[img::regex:regex][*::0:string]' => qq{

}, '[img::regex:regex][*::0:regex]' => qq{

}, '[img::regex:regex][*::0:sub]' => qq{

}, '[img::regex:regex][*::1:undef]' => qq{

}, '[img::regex:regex][*::1:0]' => qq{

}, '[img::regex:regex][*::1:1]' => qq{

}, '[img::regex:regex][*::1:string]' => qq{

}, '[img::regex:regex][*::1:regex]' => qq{

}, '[img::regex:regex][*::1:sub]' => qq{

}, '[img::regex:regex][*::string:undef]' => qq{

}, '[img::regex:regex][*::string:0]' => qq{

}, '[img::regex:regex][*::string:1]' => qq{

}, '[img::regex:regex][*::string:string]' => qq{

}, '[img::regex:regex][*::string:regex]' => qq{

}, '[img::regex:regex][*::string:sub]' => qq{

}, '[img::regex:regex][*::regex:undef]' => qq{

}, '[img::regex:regex][*::regex:0]' => qq{

}, '[img::regex:regex][*::regex:1]' => qq{

}, '[img::regex:regex][*::regex:string]' => qq{

}, '[img::regex:regex][*::regex:regex]' => qq{

}, '[img::regex:regex][*::regex:sub]' => qq{

}, '[img::regex:regex][*::sub:undef]' => qq{

}, '[img::regex:regex][*::sub:0]' => qq{

}, '[img::regex:regex][*::sub:1]' => qq{

}, '[img::regex:regex][*::sub:string]' => qq{

}, '[img::regex:regex][*::sub:regex]' => qq{

}, '[img::regex:regex][*::sub:sub]' => qq{

}, '[img::regex:sub][*::undef:undef]' => qq{${id_iat}

}, '[img::regex:sub][*::undef:0]' => qq{${id_iat}

}, '[img::regex:sub][*::undef:1]' => qq{${id_iat}

}, '[img::regex:sub][*::undef:string]' => qq{${id_iat}

}, '[img::regex:sub][*::undef:regex]' => qq{${id_iat}

}, '[img::regex:sub][*::undef:sub]' => qq{${id_iat}

}, '[img::regex:sub][*::0:undef]' => qq{${id_iat}

}, '[img::regex:sub][*::0:0]' => qq{${id_iat}

}, '[img::regex:sub][*::0:1]' => qq{${id_iat}

}, '[img::regex:sub][*::0:string]' => qq{${id_iat}

}, '[img::regex:sub][*::0:regex]' => qq{${id_iat}

}, '[img::regex:sub][*::0:sub]' => qq{${id_iat}

}, '[img::regex:sub][*::1:undef]' => qq{${id_iat}

}, '[img::regex:sub][*::1:0]' => qq{${id_iat}

}, '[img::regex:sub][*::1:1]' => qq{${id_iat}

}, '[img::regex:sub][*::1:string]' => qq{${id_iat}

}, '[img::regex:sub][*::1:regex]' => qq{${id_iat}

}, '[img::regex:sub][*::1:sub]' => qq{${id_iat}

}, '[img::regex:sub][*::string:undef]' => qq{${id_iat}

}, '[img::regex:sub][*::string:0]' => qq{${id_iat}

}, '[img::regex:sub][*::string:1]' => qq{${id_iat}

}, '[img::regex:sub][*::string:string]' => qq{${id_iat}

}, '[img::regex:sub][*::string:regex]' => qq{${id_iat}

}, '[img::regex:sub][*::string:sub]' => qq{${id_iat}

}, '[img::regex:sub][*::regex:undef]' => qq{${id_iat}

}, '[img::regex:sub][*::regex:0]' => qq{${id_iat}

}, '[img::regex:sub][*::regex:1]' => qq{${id_iat}

}, '[img::regex:sub][*::regex:string]' => qq{${id_iat}

}, '[img::regex:sub][*::regex:regex]' => qq{${id_iat}

}, '[img::regex:sub][*::regex:sub]' => qq{${id_iat}

}, '[img::regex:sub][*::sub:undef]' => qq{${id_iat}

}, '[img::regex:sub][*::sub:0]' => qq{${id_iat}

}, '[img::regex:sub][*::sub:1]' => qq{${id_iat}

}, '[img::regex:sub][*::sub:string]' => qq{${id_iat}

}, '[img::regex:sub][*::sub:regex]' => qq{${id_iat}

}, '[img::regex:sub][*::sub:sub]' => qq{${id_iat}

}, '[img::sub:undef][*::undef:undef]' => qq{bar

}, '[img::sub:undef][*::undef:0]' => qq{

}, '[img::sub:undef][*::undef:1]' => qq{bar

}, '[img::sub:undef][*::undef:string]' => qq{

}, '[img::sub:undef][*::undef:regex]' => qq{

}, '[img::sub:undef][*::undef:sub]' => qq{${dd_iat}

}, '[img::sub:undef][*::0:undef]' => qq{bar

}, '[img::sub:undef][*::0:0]' => qq{

}, '[img::sub:undef][*::0:1]' => qq{bar

}, '[img::sub:undef][*::0:string]' => qq{

}, '[img::sub:undef][*::0:regex]' => qq{

}, '[img::sub:undef][*::0:sub]' => qq{${dd_iat}

}, '[img::sub:undef][*::1:undef]' => qq{bar

}, '[img::sub:undef][*::1:0]' => qq{

}, '[img::sub:undef][*::1:1]' => qq{bar

}, '[img::sub:undef][*::1:string]' => qq{

}, '[img::sub:undef][*::1:regex]' => qq{

}, '[img::sub:undef][*::1:sub]' => qq{${dd_iat}

}, '[img::sub:undef][*::string:undef]' => qq{bar

}, '[img::sub:undef][*::string:0]' => qq{

}, '[img::sub:undef][*::string:1]' => qq{bar

}, '[img::sub:undef][*::string:string]' => qq{

}, '[img::sub:undef][*::string:regex]' => qq{

}, '[img::sub:undef][*::string:sub]' => qq{${dd_iat}

}, '[img::sub:undef][*::regex:undef]' => qq{bar

}, '[img::sub:undef][*::regex:0]' => qq{

}, '[img::sub:undef][*::regex:1]' => qq{bar

}, '[img::sub:undef][*::regex:string]' => qq{

}, '[img::sub:undef][*::regex:regex]' => qq{

}, '[img::sub:undef][*::regex:sub]' => qq{${dd_iat}

}, '[img::sub:undef][*::sub:undef]' => qq{bar

}, '[img::sub:undef][*::sub:0]' => qq{

}, '[img::sub:undef][*::sub:1]' => qq{bar

}, '[img::sub:undef][*::sub:string]' => qq{

}, '[img::sub:undef][*::sub:regex]' => qq{

}, '[img::sub:undef][*::sub:sub]' => qq{${dd_iat}

}, '[img::sub:0][*::undef:undef]' => qq{

}, '[img::sub:0][*::undef:0]' => qq{

}, '[img::sub:0][*::undef:1]' => qq{

}, '[img::sub:0][*::undef:string]' => qq{

}, '[img::sub:0][*::undef:regex]' => qq{

}, '[img::sub:0][*::undef:sub]' => qq{

}, '[img::sub:0][*::0:undef]' => qq{

}, '[img::sub:0][*::0:0]' => qq{

}, '[img::sub:0][*::0:1]' => qq{

}, '[img::sub:0][*::0:string]' => qq{

}, '[img::sub:0][*::0:regex]' => qq{

}, '[img::sub:0][*::0:sub]' => qq{

}, '[img::sub:0][*::1:undef]' => qq{

}, '[img::sub:0][*::1:0]' => qq{

}, '[img::sub:0][*::1:1]' => qq{

}, '[img::sub:0][*::1:string]' => qq{

}, '[img::sub:0][*::1:regex]' => qq{

}, '[img::sub:0][*::1:sub]' => qq{

}, '[img::sub:0][*::string:undef]' => qq{

}, '[img::sub:0][*::string:0]' => qq{

}, '[img::sub:0][*::string:1]' => qq{

}, '[img::sub:0][*::string:string]' => qq{

}, '[img::sub:0][*::string:regex]' => qq{

}, '[img::sub:0][*::string:sub]' => qq{

}, '[img::sub:0][*::regex:undef]' => qq{

}, '[img::sub:0][*::regex:0]' => qq{

}, '[img::sub:0][*::regex:1]' => qq{

}, '[img::sub:0][*::regex:string]' => qq{

}, '[img::sub:0][*::regex:regex]' => qq{

}, '[img::sub:0][*::regex:sub]' => qq{

}, '[img::sub:0][*::sub:undef]' => qq{

}, '[img::sub:0][*::sub:0]' => qq{

}, '[img::sub:0][*::sub:1]' => qq{

}, '[img::sub:0][*::sub:string]' => qq{

}, '[img::sub:0][*::sub:regex]' => qq{

}, '[img::sub:0][*::sub:sub]' => qq{

}, '[img::sub:1][*::undef:undef]' => qq{bar

}, '[img::sub:1][*::undef:0]' => qq{bar

}, '[img::sub:1][*::undef:1]' => qq{bar

}, '[img::sub:1][*::undef:string]' => qq{bar

}, '[img::sub:1][*::undef:regex]' => qq{bar

}, '[img::sub:1][*::undef:sub]' => qq{bar

}, '[img::sub:1][*::0:undef]' => qq{bar

}, '[img::sub:1][*::0:0]' => qq{bar

}, '[img::sub:1][*::0:1]' => qq{bar

}, '[img::sub:1][*::0:string]' => qq{bar

}, '[img::sub:1][*::0:regex]' => qq{bar

}, '[img::sub:1][*::0:sub]' => qq{bar

}, '[img::sub:1][*::1:undef]' => qq{bar

}, '[img::sub:1][*::1:0]' => qq{bar

}, '[img::sub:1][*::1:1]' => qq{bar

}, '[img::sub:1][*::1:string]' => qq{bar

}, '[img::sub:1][*::1:regex]' => qq{bar

}, '[img::sub:1][*::1:sub]' => qq{bar

}, '[img::sub:1][*::string:undef]' => qq{bar

}, '[img::sub:1][*::string:0]' => qq{bar

}, '[img::sub:1][*::string:1]' => qq{bar

}, '[img::sub:1][*::string:string]' => qq{bar

}, '[img::sub:1][*::string:regex]' => qq{bar

}, '[img::sub:1][*::string:sub]' => qq{bar

}, '[img::sub:1][*::regex:undef]' => qq{bar

}, '[img::sub:1][*::regex:0]' => qq{bar

}, '[img::sub:1][*::regex:1]' => qq{bar

}, '[img::sub:1][*::regex:string]' => qq{bar

}, '[img::sub:1][*::regex:regex]' => qq{bar

}, '[img::sub:1][*::regex:sub]' => qq{bar

}, '[img::sub:1][*::sub:undef]' => qq{bar

}, '[img::sub:1][*::sub:0]' => qq{bar

}, '[img::sub:1][*::sub:1]' => qq{bar

}, '[img::sub:1][*::sub:string]' => qq{bar

}, '[img::sub:1][*::sub:regex]' => qq{bar

}, '[img::sub:1][*::sub:sub]' => qq{bar

}, '[img::sub:string][*::undef:undef]' => qq{

}, '[img::sub:string][*::undef:0]' => qq{

}, '[img::sub:string][*::undef:1]' => qq{

}, '[img::sub:string][*::undef:string]' => qq{

}, '[img::sub:string][*::undef:regex]' => qq{

}, '[img::sub:string][*::undef:sub]' => qq{

}, '[img::sub:string][*::0:undef]' => qq{

}, '[img::sub:string][*::0:0]' => qq{

}, '[img::sub:string][*::0:1]' => qq{

}, '[img::sub:string][*::0:string]' => qq{

}, '[img::sub:string][*::0:regex]' => qq{

}, '[img::sub:string][*::0:sub]' => qq{

}, '[img::sub:string][*::1:undef]' => qq{

}, '[img::sub:string][*::1:0]' => qq{

}, '[img::sub:string][*::1:1]' => qq{

}, '[img::sub:string][*::1:string]' => qq{

}, '[img::sub:string][*::1:regex]' => qq{

}, '[img::sub:string][*::1:sub]' => qq{

}, '[img::sub:string][*::string:undef]' => qq{

}, '[img::sub:string][*::string:0]' => qq{

}, '[img::sub:string][*::string:1]' => qq{

}, '[img::sub:string][*::string:string]' => qq{

}, '[img::sub:string][*::string:regex]' => qq{

}, '[img::sub:string][*::string:sub]' => qq{

}, '[img::sub:string][*::regex:undef]' => qq{

}, '[img::sub:string][*::regex:0]' => qq{

}, '[img::sub:string][*::regex:1]' => qq{

}, '[img::sub:string][*::regex:string]' => qq{

}, '[img::sub:string][*::regex:regex]' => qq{

}, '[img::sub:string][*::regex:sub]' => qq{

}, '[img::sub:string][*::sub:undef]' => qq{

}, '[img::sub:string][*::sub:0]' => qq{

}, '[img::sub:string][*::sub:1]' => qq{

}, '[img::sub:string][*::sub:string]' => qq{

}, '[img::sub:string][*::sub:regex]' => qq{

}, '[img::sub:string][*::sub:sub]' => qq{

}, '[img::sub:regex][*::undef:undef]' => qq{

}, '[img::sub:regex][*::undef:0]' => qq{

}, '[img::sub:regex][*::undef:1]' => qq{

}, '[img::sub:regex][*::undef:string]' => qq{

}, '[img::sub:regex][*::undef:regex]' => qq{

}, '[img::sub:regex][*::undef:sub]' => qq{

}, '[img::sub:regex][*::0:undef]' => qq{

}, '[img::sub:regex][*::0:0]' => qq{

}, '[img::sub:regex][*::0:1]' => qq{

}, '[img::sub:regex][*::0:string]' => qq{

}, '[img::sub:regex][*::0:regex]' => qq{

}, '[img::sub:regex][*::0:sub]' => qq{

}, '[img::sub:regex][*::1:undef]' => qq{

}, '[img::sub:regex][*::1:0]' => qq{

}, '[img::sub:regex][*::1:1]' => qq{

}, '[img::sub:regex][*::1:string]' => qq{

}, '[img::sub:regex][*::1:regex]' => qq{

}, '[img::sub:regex][*::1:sub]' => qq{

}, '[img::sub:regex][*::string:undef]' => qq{

}, '[img::sub:regex][*::string:0]' => qq{

}, '[img::sub:regex][*::string:1]' => qq{

}, '[img::sub:regex][*::string:string]' => qq{

}, '[img::sub:regex][*::string:regex]' => qq{

}, '[img::sub:regex][*::string:sub]' => qq{

}, '[img::sub:regex][*::regex:undef]' => qq{

}, '[img::sub:regex][*::regex:0]' => qq{

}, '[img::sub:regex][*::regex:1]' => qq{

}, '[img::sub:regex][*::regex:string]' => qq{

}, '[img::sub:regex][*::regex:regex]' => qq{

}, '[img::sub:regex][*::regex:sub]' => qq{

}, '[img::sub:regex][*::sub:undef]' => qq{

}, '[img::sub:regex][*::sub:0]' => qq{

}, '[img::sub:regex][*::sub:1]' => qq{

}, '[img::sub:regex][*::sub:string]' => qq{

}, '[img::sub:regex][*::sub:regex]' => qq{

}, '[img::sub:regex][*::sub:sub]' => qq{

}, '[img::sub:sub][*::undef:undef]' => qq{${id_iat}

}, '[img::sub:sub][*::undef:0]' => qq{${id_iat}

}, '[img::sub:sub][*::undef:1]' => qq{${id_iat}

}, '[img::sub:sub][*::undef:string]' => qq{${id_iat}

}, '[img::sub:sub][*::undef:regex]' => qq{${id_iat}

}, '[img::sub:sub][*::undef:sub]' => qq{${id_iat}

}, '[img::sub:sub][*::0:undef]' => qq{${id_iat}

}, '[img::sub:sub][*::0:0]' => qq{${id_iat}

}, '[img::sub:sub][*::0:1]' => qq{${id_iat}

}, '[img::sub:sub][*::0:string]' => qq{${id_iat}

}, '[img::sub:sub][*::0:regex]' => qq{${id_iat}

}, '[img::sub:sub][*::0:sub]' => qq{${id_iat}

}, '[img::sub:sub][*::1:undef]' => qq{${id_iat}

}, '[img::sub:sub][*::1:0]' => qq{${id_iat}

}, '[img::sub:sub][*::1:1]' => qq{${id_iat}

}, '[img::sub:sub][*::1:string]' => qq{${id_iat}

}, '[img::sub:sub][*::1:regex]' => qq{${id_iat}

}, '[img::sub:sub][*::1:sub]' => qq{${id_iat}

}, '[img::sub:sub][*::string:undef]' => qq{${id_iat}

}, '[img::sub:sub][*::string:0]' => qq{${id_iat}

}, '[img::sub:sub][*::string:1]' => qq{${id_iat}

}, '[img::sub:sub][*::string:string]' => qq{${id_iat}

}, '[img::sub:sub][*::string:regex]' => qq{${id_iat}

}, '[img::sub:sub][*::string:sub]' => qq{${id_iat}

}, '[img::sub:sub][*::regex:undef]' => qq{${id_iat}

}, '[img::sub:sub][*::regex:0]' => qq{${id_iat}

}, '[img::sub:sub][*::regex:1]' => qq{${id_iat}

}, '[img::sub:sub][*::regex:string]' => qq{${id_iat}

}, '[img::sub:sub][*::regex:regex]' => qq{${id_iat}

}, '[img::sub:sub][*::regex:sub]' => qq{${id_iat}

}, '[img::sub:sub][*::sub:undef]' => qq{${id_iat}

}, '[img::sub:sub][*::sub:0]' => qq{${id_iat}

}, '[img::sub:sub][*::sub:1]' => qq{${id_iat}

}, '[img::sub:sub][*::sub:string]' => qq{${id_iat}

}, '[img::sub:sub][*::sub:regex]' => qq{${id_iat}

}, '[img::sub:sub][*::sub:sub]' => qq{${id_iat}

}, ); } tags000755000765000024 012715050062 17300 5ustar00clintonstaff000000000000HTML-StripScripts-1.06/examplesREADME100644000765000024 254712715050062 20330 0ustar00clintonstaff000000000000HTML-StripScripts-1.06/examples/tagsOverriding HTML::StripScripts to add tags ----------------------------------------- The allowed tags and attributes in HTML::StripScripts is not complete. Unsafe tags have been specifically left out (eg