~ubuntu-branches/ubuntu/raring/qtwebkit-source/raring-proposed

« back to all changes in this revision

Viewing changes to Source/WebCore/loader/appcache/ManifestParser.cpp

  • Committer: Package Import Robot
  • Author(s): Jonathan Riddell
  • Date: 2013-02-18 14:24:18 UTC
  • Revision ID: package-import@ubuntu.com-20130218142418-eon0jmjg3nj438uy
Tags: upstream-2.3
ImportĀ upstreamĀ versionĀ 2.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2008 Apple Inc. All Rights Reserved.
 
3
 *
 
4
 * Redistribution and use in source and binary forms, with or without
 
5
 * modification, are permitted provided that the following conditions
 
6
 * are met:
 
7
 * 1. Redistributions of source code must retain the above copyright
 
8
 *    notice, this list of conditions and the following disclaimer.
 
9
 * 2. Redistributions in binary form must reproduce the above copyright
 
10
 *    notice, this list of conditions and the following disclaimer in the
 
11
 *    documentation and/or other materials provided with the distribution.
 
12
 *
 
13
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 
14
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 
15
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 
16
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
 
17
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 
18
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 
19
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 
20
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 
21
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 
22
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 
23
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 
24
 */
 
25
 
 
26
#include "config.h"
 
27
#include "ManifestParser.h"
 
28
 
 
29
#include "KURL.h"
 
30
#include "TextResourceDecoder.h"
 
31
#include <wtf/unicode/CharacterNames.h>
 
32
 
 
33
using namespace std;
 
34
 
 
35
namespace WebCore {
 
36
 
 
37
enum Mode { Explicit, Fallback, OnlineWhitelist, Unknown };
 
38
    
 
39
bool parseManifest(const KURL& manifestURL, const char* data, int length, Manifest& manifest)
 
40
{
 
41
    ASSERT(manifest.explicitURLs.isEmpty());
 
42
    ASSERT(manifest.onlineWhitelistedURLs.isEmpty());
 
43
    ASSERT(manifest.fallbackURLs.isEmpty());
 
44
    manifest.allowAllNetworkRequests = false;
 
45
 
 
46
    Mode mode = Explicit;
 
47
 
 
48
    RefPtr<TextResourceDecoder> decoder = TextResourceDecoder::create("text/cache-manifest", "UTF-8");
 
49
    String s = decoder->decode(data, length);
 
50
    s.append(decoder->flush());
 
51
    
 
52
    // Look for the magic signature: "^\xFEFF?CACHE MANIFEST[ \t]?" (the BOM is removed by TextResourceDecoder).
 
53
    // Example: "CACHE MANIFEST #comment" is a valid signature.
 
54
    // Example: "CACHE MANIFEST;V2" is not.
 
55
    if (!s.startsWith("CACHE MANIFEST"))
 
56
        return false;
 
57
    
 
58
    const UChar* end = s.characters() + s.length();    
 
59
    const UChar* p = s.characters() + 14; // "CACHE MANIFEST" is 14 characters.
 
60
 
 
61
    if (p < end && *p != ' ' && *p != '\t' && *p != '\n' && *p != '\r')
 
62
        return false;
 
63
 
 
64
    // Skip to the end of the line.
 
65
    while (p < end && *p != '\r' && *p != '\n')
 
66
        p++;
 
67
 
 
68
    while (1) {
 
69
        // Skip whitespace
 
70
        while (p < end && (*p == '\n' || *p == '\r' || *p == ' ' || *p == '\t'))
 
71
            p++;
 
72
        
 
73
        if (p == end)
 
74
            break;
 
75
        
 
76
        const UChar* lineStart = p;
 
77
        
 
78
        // Find the end of the line
 
79
        while (p < end && *p != '\r' && *p != '\n')
 
80
            p++;
 
81
        
 
82
        // Check if we have a comment
 
83
        if (*lineStart == '#')
 
84
            continue;
 
85
        
 
86
        // Get rid of trailing whitespace
 
87
        const UChar* tmp = p - 1;
 
88
        while (tmp > lineStart && (*tmp == ' ' || *tmp == '\t'))
 
89
            tmp--;
 
90
        
 
91
        String line(lineStart, tmp - lineStart + 1);
 
92
 
 
93
        if (line == "CACHE:") 
 
94
            mode = Explicit;
 
95
        else if (line == "FALLBACK:")
 
96
            mode = Fallback;
 
97
        else if (line == "NETWORK:")
 
98
            mode = OnlineWhitelist;
 
99
        else if (line.endsWith(':'))
 
100
            mode = Unknown;
 
101
        else if (mode == Unknown)
 
102
            continue;
 
103
        else if (mode == Explicit || mode == OnlineWhitelist) {
 
104
            const UChar* p = line.characters();
 
105
            const UChar* lineEnd = p + line.length();
 
106
            
 
107
            // Look for whitespace separating the URL from subsequent ignored tokens.
 
108
            while (p < lineEnd && *p != '\t' && *p != ' ') 
 
109
                p++;
 
110
 
 
111
            if (mode == OnlineWhitelist && p - line.characters() == 1 && *line.characters() == '*') {
 
112
                // Wildcard was found.
 
113
                manifest.allowAllNetworkRequests = true;
 
114
                continue;
 
115
            }
 
116
 
 
117
            KURL url(manifestURL, String(line.characters(), p - line.characters()));
 
118
            
 
119
            if (!url.isValid())
 
120
                continue;
 
121
 
 
122
            if (url.hasFragmentIdentifier())
 
123
                url.removeFragmentIdentifier();
 
124
            
 
125
            if (!equalIgnoringCase(url.protocol(), manifestURL.protocol()))
 
126
                continue;
 
127
            
 
128
            if (mode == Explicit && manifestURL.protocolIs("https") && !protocolHostAndPortAreEqual(manifestURL, url))
 
129
                continue;
 
130
            
 
131
            if (mode == Explicit)
 
132
                manifest.explicitURLs.add(url.string());
 
133
            else
 
134
                manifest.onlineWhitelistedURLs.append(url);
 
135
            
 
136
        } else if (mode == Fallback) {
 
137
            const UChar* p = line.characters();
 
138
            const UChar* lineEnd = p + line.length();
 
139
            
 
140
            // Look for whitespace separating the two URLs
 
141
            while (p < lineEnd && *p != '\t' && *p != ' ') 
 
142
                p++;
 
143
 
 
144
            if (p == lineEnd) {
 
145
                // There was no whitespace separating the URLs.
 
146
                continue;
 
147
            }
 
148
            
 
149
            KURL namespaceURL(manifestURL, String(line.characters(), p - line.characters()));
 
150
            if (!namespaceURL.isValid())
 
151
                continue;
 
152
            if (namespaceURL.hasFragmentIdentifier())
 
153
                namespaceURL.removeFragmentIdentifier();
 
154
 
 
155
            if (!protocolHostAndPortAreEqual(manifestURL, namespaceURL))
 
156
                continue;
 
157
                                   
 
158
            // Skip whitespace separating fallback namespace from URL.
 
159
            while (p < lineEnd && (*p == '\t' || *p == ' '))
 
160
                p++;
 
161
 
 
162
            // Look for whitespace separating the URL from subsequent ignored tokens.
 
163
            const UChar* fallbackStart = p;
 
164
            while (p < lineEnd && *p != '\t' && *p != ' ') 
 
165
                p++;
 
166
 
 
167
            KURL fallbackURL(manifestURL, String(fallbackStart, p - fallbackStart));
 
168
            if (!fallbackURL.isValid())
 
169
                continue;
 
170
            if (fallbackURL.hasFragmentIdentifier())
 
171
                fallbackURL.removeFragmentIdentifier();
 
172
 
 
173
            if (!protocolHostAndPortAreEqual(manifestURL, fallbackURL))
 
174
                continue;
 
175
 
 
176
            manifest.fallbackURLs.append(make_pair(namespaceURL, fallbackURL));            
 
177
        } else 
 
178
            ASSERT_NOT_REACHED();
 
179
    }
 
180
 
 
181
    return true;
 
182
}
 
183
 
 
184
}