/[suikacvs]/markup/html/whatpm/Whatpm/CacheManifest.pm
Suika

Contents of /markup/html/whatpm/Whatpm/CacheManifest.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.7 - (hide annotations) (download)
Sat Aug 16 07:35:22 2008 UTC (17 years, 11 months ago) by wakaba
Branch: MAIN
Changes since 1.6: +72 -66 lines
++ whatpm/Whatpm/ChangeLog	16 Aug 2008 07:34:18 -0000
	* CacheManifest.pm: Support for new style of error
	reports.

	* HTML.pm.src: Set line=1, column=1 to the document node.

2008-08-16  Wakaba  <wakaba@suika.fam.cx>

++ whatpm/Whatpm/CSS/ChangeLog	16 Aug 2008 07:34:47 -0000
2008-08-16  Wakaba  <wakaba@suika.fam.cx>

	* MediaQueryParser.pm, SelectorsParser.pm, Parser.pm: Support
	for new style of error reports.

1 wakaba 1.1 package Whatpm::CacheManifest;
2     use strict;
3 wakaba 1.7 our $VERSION=do{my @r=(q$Revision: 1.6 $=~/\d+/g);sprintf "%d."."%02d" x $#r,@r};
4 wakaba 1.1 require Message::URI::URIReference;
5    
6 wakaba 1.7 sub parse_byte_string ($$$$;$$) {
7 wakaba 1.1 require Encode;
8     my $s = Encode::decode ('utf-8', $_[1]);
9     return $_[0]->_parse (\$s, $_[2], $_[3], $_[4] || sub {
10     my %err = @_;
11     warn $err{type}, "\n";
12 wakaba 1.7 }, $_[5]);
13 wakaba 1.1 } # parse_byte_string
14    
15 wakaba 1.7 sub parse_char_string ($$$$;$$) {
16 wakaba 1.1 return $_[0]->_parse (\($_[1]), $_[2], $_[3], $_[4] || sub {
17     my %err = @_;
18     warn $err{type}, "\n";
19 wakaba 1.7 }, $_[5]);
20 wakaba 1.1 } # parse_char_string
21    
22 wakaba 1.7 my $default_error_levels = {
23     must => 'm',
24     info => 'i',
25     };
26    
27     sub _parse ($$$$$$) {
28     #my (undef, $input, $manifest_uri, $base_uri, $onerror, $levels) = @_;
29 wakaba 1.1
30     ## NOTE: A manifest MUST be labeled as text/cache-manifest. (This should
31     ## be checked in upper-level).
32     ## NOTE: No "MUST" for being UTF-8.
33     ## NOTE: A |text/cache-manifest| MUST be a cache manifest.
34     ## NOTE: Newlines MUST be CR/CRLF/LF. (We don't and can't check this.)
35    
36 wakaba 1.2 ## ISSUE: In RFC 2046: "The specification for any future subtypes of "text" must specify whether or not they will also utilize a "charset" parameter"
37    
38 wakaba 1.1 my $m_uri = Message::DOM::DOMImplementation->create_uri_reference ($_[2]);
39     my $m_scheme = $m_uri->uri_scheme;
40    
41     my $onerror = $_[4];
42 wakaba 1.7 my $levels = $_[5] || $default_error_levels;
43    
44 wakaba 1.1 my $line_number = 1;
45    
46 wakaba 1.4 ## Same origin with the manifest's URI
47     my $same_origin = sub {
48     ## NOTE: Step numbers in this function corresponds to those in the
49     ## algorithm for determining the origin of a URI specified in HTML5.
50 wakaba 1.1
51 wakaba 1.4 ## 1. and 2.
52 wakaba 1.1 my $u1 = shift;
53 wakaba 1.4 #my $m_uri = $m_uri;
54    
55 wakaba 1.7
56 wakaba 1.4 ## 3.
57     return 0 unless defined $u1->uri_authority;
58     return 0 unless defined $m_uri->uri_authority;
59     ## TODO: In addition, in the case of URIs with non-server-based authority
60     ## it must also return 0.
61 wakaba 1.1
62 wakaba 1.4 ## 4.
63 wakaba 1.3 unless (lc $u1->uri_scheme eq lc $m_scheme) { ## TODO: case
64 wakaba 1.1 return 0;
65     }
66 wakaba 1.4 ## TODO: Return if $u1->uri_scheme is not a supported scheme.
67     ## NOTE: $m_scheme is always a supported URI scheme, otherwise
68     ## the manifest itself cannot be retrieved.
69 wakaba 1.1
70 wakaba 1.4 ## 5., 6., and 7.
71 wakaba 1.1 return 0 unless $u1->uri_host eq $m_uri->uri_host;
72 wakaba 1.4 ## TODO: IDNA ToASCII
73    
74     ## 8.
75 wakaba 1.1 return 0 unless $u1->uri_port eq $m_uri->uri_port;
76 wakaba 1.4 ## TODO: default port
77 wakaba 1.1
78 wakaba 1.4 ## 9.
79 wakaba 1.1 return 1;
80 wakaba 1.4 }; # $same_origin
81 wakaba 1.1
82     ## Step 5
83     my $input = $_[1];
84    
85     ## Step 1: MUST bytes --UTF-8--> characters.
86 wakaba 1.5 ## NOTE: illegal(s) -> U+FFFD, #U+0000 -> U+FFFD (commented out in r1553).
87     #$$input =~ tr/\x00/\x{FFFD}/;
88 wakaba 1.1
89     ## Step 2
90     my $explicit_uris = [];
91    
92     ## Step 3
93     my $fallback_uris = {};
94    
95     ## Step 4
96     my $online_whitelist_uris = [];
97    
98     ## Step 6
99     pos ($$input) = 0;
100    
101     ## Step 7
102     ## Skip BOM ## NOTE: MAY in syntax.
103    
104     ## Step 8-10
105     unless ($$input =~ /^CACHE MANIFEST[\x20\x09]*(?![^\x0D\x0A])/gc) {
106 wakaba 1.7 $onerror->(type => 'not manifest', level => $levels->{must},
107 wakaba 1.1 line => $line_number, column => 1); ## NOTE: MUST in syntax.
108     return; ## Not a manifest.
109     }
110    
111     ## Step 11
112     ## This is a cache manifest.
113    
114     ## Step 12
115     my $mode = 'explicit';
116    
117     ## NOTE: MUST be (blank line|comment|section head|data for the current
118     ## section)*.
119    
120     ## Step 13
121     START_OF_LINE: while (pos $$input < length $$input) {
122     $$input =~ /([\x0A\x0D\x20\x09]+)/gc;
123     my $v = $1;
124 wakaba 1.4 $line_number++ for $v =~ /\x0D\x0A?|\x0A/g;
125 wakaba 1.1
126     ## Step 14
127     $$input =~ /([^\x0A\x0D]*)/gc;
128     my $line = $1;
129    
130     ## Step 15
131 wakaba 1.3 $line =~ s/[\x20\x09]+\z//;
132 wakaba 1.1
133 wakaba 1.3 ## Step 16-17
134     if ($line eq '' or $line =~ /^#/) {
135     next START_OF_LINE;
136     }
137 wakaba 1.1
138     if ($line eq 'CACHE:') {
139 wakaba 1.3 ## Step 18
140 wakaba 1.1 $mode = 'explicit';
141     next START_OF_LINE;
142     } elsif ($line eq 'FALLBACK:') {
143 wakaba 1.3 ## Step 19
144 wakaba 1.1 $mode = 'fallback';
145     next START_OF_LINE;
146     } elsif ($line eq 'NETWORK:') {
147 wakaba 1.3 ## Step 20
148 wakaba 1.1 $mode = 'online whitelist';
149     next START_OF_LINE;
150     }
151    
152     ## NOTE: "URIs that are to be fallback pages associated with
153     ## opportunistic caching namespaces, and those namespaces themselves,
154     ## MUST be given in fallback sections, with the namespace being the
155     ## first URI of the data line, and the corresponding fallback page
156     ## being the second URI. All the other pages to be cached MUST be
157     ## listed in explicit sections." in writing section can't be tested.
158     ## NOTE: "URIs that the user agent is to put into the online whitelist
159     ## MUST all be specified in online whitelist sections." in writing
160     ## section can't be tested.
161    
162     ## NOTE: "Relative URIs MUST be given relative to the manifest's own URI."
163     ## requirement in writing section can't be tested.
164    
165 wakaba 1.3 ## Step 21
166 wakaba 1.1 if ($mode eq 'explicit') {
167     my $uri = Message::DOM::DOMImplementation->create_uri_reference ($line);
168    
169     unless ($uri->is_iri_reference_3987) {
170 wakaba 1.7 $onerror->(type => 'syntax error:iriref3987',
171     level => $levels->{must},
172     line => $line_number, column => 1,
173 wakaba 1.1 value => $line);
174     next START_OF_LINE; ## NOTE: MUST in syntax.
175     }
176    
177     $uri = $uri->get_absolute_reference ($_[3]);
178    
179     if (defined $uri->uri_fragment) {
180     $uri->uri_fragment (undef);
181 wakaba 1.7 $onerror->(type => 'URL fragment not allowed',
182     level => $levels->{must},
183     line => $line_number, column => 1,
184 wakaba 1.1 value => $line);
185     ## NOTE: MUST in writing section.
186     }
187    
188     my $scheme = $uri->uri_scheme;
189     unless (defined $scheme and $scheme eq $m_scheme) {
190     $onerror->(type => 'different scheme from manifest',
191 wakaba 1.7 level => $levels->{info},
192     line => $line_number, column => 1,
193 wakaba 1.1 value => $uri->uri_reference);
194     next START_OF_LINE;
195     }
196    
197     push @$explicit_uris, $uri->uri_reference;
198     } elsif ($mode eq 'fallback') {
199     my ($p1, $p2) = split /[\x20\x09]+/, $line, 2;
200    
201     unless (defined $p2) {
202 wakaba 1.7 $onerror->(type => 'no fallback entry URL',
203     level => $levels->{must},
204     line => $line_number, column => 1,
205 wakaba 1.1 value => $line);
206     next START_OF_LINE; ## NOTE: MUST in syntax.
207     }
208    
209     my $u1 = Message::DOM::DOMImplementation->create_uri_reference ($p1);
210    
211     unless ($u1->is_iri_reference_3987) {
212 wakaba 1.7 $onerror->(type => 'syntax error:iriref3987',
213     level => $levels->{must},
214     line => $line_number, column => 1,
215 wakaba 1.1 index => 0, value => $p1);
216     next START_OF_LINE; ## NOTE: MUST in syntax.
217     }
218    
219     my $u2 = Message::DOM::DOMImplementation->create_uri_reference ($p2);
220    
221     unless ($u2->is_iri_reference_3987) {
222 wakaba 1.7 $onerror->(type => 'syntax error:iriref3987',
223     level => $levels->{must},
224     line => $line_number, column => 1,
225 wakaba 1.1 index => 1, value => $p2);
226     next START_OF_LINE; ## NOTE: MUST in syntax.
227     }
228    
229     if (defined $u1->uri_fragment) {
230 wakaba 1.6 $u1->uri_fragment (undef);
231 wakaba 1.7 $onerror->(type => 'URL fragment not allowed',
232     level => $levels->{must},
233     line => $line_number, column => 1,
234 wakaba 1.1 index => 0, value => $p1);
235     ## NOTE: MUST in writing section.
236     }
237    
238     if (defined $u2->uri_fragment) {
239 wakaba 1.6 $u2->uri_fragment (undef);
240 wakaba 1.7 $onerror->(type => 'URL fragment not allowed',
241     level => $levels->{must},
242     line => $line_number, column => 1,
243 wakaba 1.1 index => 1, value => $p2);
244     ## NOTE: MUST in writing section.
245     }
246    
247     $u1 = $u1->get_absolute_reference ($_[3]);
248     $u2 = $u2->get_absolute_reference ($_[3]);
249    
250     if (exists $fallback_uris->{$u1->uri_reference}) {
251     $onerror->(type => 'duplicate oc namespace',
252 wakaba 1.7 level => $levels->{must},
253     line => $line_number, column => 1,
254 wakaba 1.1 index => 0, value => $u1->uri_reference);
255     next START_OF_LINE; ## NOTE: MUST in syntax.
256     }
257    
258 wakaba 1.4 unless ($same_origin->($u1)) {
259 wakaba 1.7 $onerror->(type => 'different origin from manifest',
260     level => $levels->{must},
261     line => $line_number, column => 1,
262 wakaba 1.1 index => 0, value => $u1->uri_reference);
263     next START_OF_LINE; ## NOTE: MUST in syntax.
264     }
265    
266     my $u2_scheme = $u2->uri_scheme;
267     unless (defined $u2_scheme and $u2_scheme eq $m_scheme) {
268     $onerror->(type => 'different scheme from manifest',
269 wakaba 1.7 level => $levels->{info},
270     line => $line_number, column => 1,
271 wakaba 1.1 index => 1, value => $u2->uri_reference);
272     next START_OF_LINE;
273     }
274    
275     $fallback_uris->{$u1->uri_reference} = $u2->uri_reference;
276     } elsif ($mode eq 'online whitelist') {
277     my $uri = Message::DOM::DOMImplementation->create_uri_reference ($line);
278    
279     unless ($uri->is_iri_reference_3987) {
280 wakaba 1.7 $onerror->(type => 'syntax error:iriref3987',
281     level => $levels->{must},
282     line => $line_number, column => 1,
283 wakaba 1.1 value => $line);
284     next START_OF_LINE; ## NOTE: MUST in syntax.
285     }
286    
287     $uri = $uri->get_absolute_reference ($_[3]);
288    
289     if (defined $uri->uri_fragment) {
290     $uri->uri_fragment (undef);
291 wakaba 1.7 $onerror->(type => 'URL fragment not allowed',
292     level => $levels->{must},
293     line => $line_number, column => 1,
294 wakaba 1.1 value => $line);
295     ## NOTE: MUST in writing section.
296     }
297    
298     my $scheme = $uri->uri_scheme;
299     unless (defined $scheme and $scheme eq $m_scheme) {
300     $onerror->(type => 'different scheme from manifest',
301 wakaba 1.7 level => $levels->{info},
302     line => $line_number, column => 1,
303 wakaba 1.1 value => $uri->uri_reference);
304     next START_OF_LINE;
305     }
306    
307     push @$online_whitelist_uris, $uri->uri_reference;
308     }
309    
310 wakaba 1.3 ## Step 22
311 wakaba 1.1 #next START_OF_LINE;
312     } # START_OF_LINE
313    
314 wakaba 1.3 ## Step 23
315     return [$explicit_uris, $fallback_uris, $online_whitelist_uris,
316     $m_uri->uri_reference];
317 wakaba 1.1 } # _parse
318    
319 wakaba 1.7 sub check_manifest ($$$;$) {
320     my (undef, $manifest, $onerror, $levels) = @_;
321 wakaba 1.1
322     my $listed = {};
323 wakaba 1.7
324     $levels ||= $default_error_levels;
325 wakaba 1.1
326     require Whatpm::URIChecker;
327    
328 wakaba 1.3 my $i = 0;
329 wakaba 1.1 for my $uri (@{$manifest->[0]}) {
330     $listed->{$uri} = 1;
331    
332     Whatpm::URIChecker->check_iri_reference ($uri, sub {
333 wakaba 1.7 $onerror->(value => $uri, @_, index => $i);
334 wakaba 1.1 });
335 wakaba 1.3
336     ## ISSUE: Literal equivalence, right?
337     if ($uri eq $manifest->[3]) {
338 wakaba 1.7 $onerror->(level => $levels->{must}, value => $uri,
339 wakaba 1.3 index => $i,
340 wakaba 1.7 type => 'same as manifest URL');
341 wakaba 1.3 }
342    
343     $i++;
344 wakaba 1.1 }
345    
346 wakaba 1.3 for my $uri1 (sort {$a cmp $b} keys %{$manifest->[1]}) {
347     Whatpm::URIChecker->check_iri_reference ($uri1, sub {
348 wakaba 1.7 $onerror->(value => $uri1, @_, index => 0);
349 wakaba 1.1 });
350    
351 wakaba 1.3 if ($uri1 eq $manifest->[3]) {
352 wakaba 1.7 $onerror->(level => $levels->{must}, value => $uri1,
353 wakaba 1.3 index => $i,
354 wakaba 1.7 type => 'same as manifest URL');
355 wakaba 1.3 }
356    
357     $i++;
358    
359     my $uri2 = $manifest->[1]->{$uri1};
360     $listed->{$uri2} = 1;
361    
362     Whatpm::URIChecker->check_iri_reference ($uri2, sub {
363 wakaba 1.7 $onerror->(value => $uri2, @_, index => 1);
364 wakaba 1.1 });
365 wakaba 1.3
366     if ($uri2 eq $manifest->[3]) {
367 wakaba 1.7 $onerror->(level => $levels->{must}, value => $uri2,
368 wakaba 1.3 index => $i,
369 wakaba 1.7 type => 'same as manifest URL');
370 wakaba 1.3 }
371    
372     $i++;
373 wakaba 1.1 }
374    
375     for my $uri (@{$manifest->[2]}) {
376     if ($listed->{$uri}) {
377     $onerror->(type => 'both in entries and whitelist',
378 wakaba 1.3 index => $i,
379 wakaba 1.7 level => $levels->{must}, value => $uri);
380 wakaba 1.1 ## NOTE: MUST in writing section.
381     }
382    
383     Whatpm::URIChecker->check_iri_reference ($uri, sub {
384 wakaba 1.7 $onerror->(value => $uri, @_, index => $i);
385 wakaba 1.1 });
386 wakaba 1.3
387     if ($uri eq $manifest->[3]) {
388 wakaba 1.7 $onerror->(level => $levels->{must}, value => $uri,
389 wakaba 1.3 index => $i,
390 wakaba 1.7 type => 'same as manifest URL');
391 wakaba 1.3 }
392    
393     $i++;
394 wakaba 1.1 }
395     } # check_manifest
396    
397    
398     =head1 LICENSE
399    
400 wakaba 1.3 Copyright 2007-2008 Wakaba <[email protected]>
401 wakaba 1.1
402     This library is free software; you can redistribute it
403     and/or modify it under the same terms as Perl itself.
404    
405     =cut
406    
407     1;
408 wakaba 1.7 # $Date: 2008/05/16 13:56:16 $

[email protected]
ViewVC Help
Powered by ViewVC 1.1.24