Changeset 69072 in webkit


Ignore:
Timestamp:
Oct 4, 2010 10:06:00 PM (13 years ago)
Author:
commit-queue@webkit.org
Message:

2010-10-04 Patrick Gansterer <paroga@paroga.com>

Reviewed by Darin Adler.

Add Base64DecodePolicy option at base64Decode()
https://bugs.webkit.org/show_bug.cgi?id=41510

  • fast/dom/Window/atob-btoa-expected.txt:
  • fast/dom/Window/atob-btoa.html:
  • platform/mac/fast/loader/user-stylesheet-fast-path-expected.txt:
  • platform/mac/fast/loader/user-stylesheet-fast-path.html: Added additional data urls tests.

2010-10-04 Patrick Gansterer <paroga@paroga.com>

Reviewed by Darin Adler.

Add Base64DecodePolicy option at base64Decode()
https://bugs.webkit.org/show_bug.cgi?id=41510

Add an option for ignoring characters in base64 data.
This is necessary for decoding data urls.

Also add an overload to decode WebCore::String directly.

  • page/DOMWindow.cpp: (WebCore::DOMWindow::atob):
  • page/Page.cpp: (WebCore::Page::userStyleSheetLocationChanged):
  • platform/text/Base64.cpp: (WebCore::base64Encode): (WebCore::base64Decode): (WebCore::base64DecodeInternal):
  • platform/text/Base64.h: (WebCore::):
Location:
trunk
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r69068 r69072  
     12010-10-04  Patrick Gansterer  <paroga@paroga.com>
     2
     3        Reviewed by Darin Adler.
     4
     5        Add Base64DecodePolicy option at base64Decode()
     6        https://bugs.webkit.org/show_bug.cgi?id=41510
     7
     8        * fast/dom/Window/atob-btoa-expected.txt:
     9        * fast/dom/Window/atob-btoa.html:
     10        * platform/mac/fast/loader/user-stylesheet-fast-path-expected.txt:
     11        * platform/mac/fast/loader/user-stylesheet-fast-path.html: Added additional data urls tests.
     12
    1132010-10-04  Yael Aharon  <yael.aharon@nokia.com>
    214
  • trunk/LayoutTests/fast/dom/Window/atob-btoa-expected.txt

    r55637 r69072  
    3636PASS window.atob("zz") is "Ï"
    3737PASS window.atob("zzz") is "Ï<"
     38PASS window.atob("zzz=") is "Ï<"
     39PASS window.atob("zzz==") is "Ï<"
     40PASS window.atob("zzz===") is "Ï<"
     41PASS window.atob("zzz====") is "Ï<"
    3842PASS window.atob("zzzz") is "Ï<ó"
    3943PASS window.atob("zzzzz") threw exception Error: INVALID_CHARACTER_ERR: DOM Exception 5.
     44PASS window.atob("z=zz") threw exception Error: INVALID_CHARACTER_ERR: DOM Exception 5.
    4045PASS window.atob("=") threw exception Error: INVALID_CHARACTER_ERR: DOM Exception 5.
    4146PASS window.atob("==") threw exception Error: INVALID_CHARACTER_ERR: DOM Exception 5.
  • trunk/LayoutTests/fast/dom/Window/atob-btoa.html

    r55637 r69072  
    4949shouldBe('window.atob("zz")', '"Ï"');
    5050shouldBe('window.atob("zzz")', '"Ï\u003C"');
     51shouldBe('window.atob("zzz=")', '"Ï\u003C"');
     52shouldBe('window.atob("zzz==")', '"Ï\u003C"');
     53shouldBe('window.atob("zzz===")', '"Ï\u003C"');
     54shouldBe('window.atob("zzz====")', '"Ï\u003C"');
    5155shouldBe('window.atob("zzzz")', '"Ï\u003Có"');
    5256shouldThrow('window.atob("zzzzz")');
     57shouldThrow('window.atob("z=zz")');
    5358shouldThrow('window.atob("=")');
    5459shouldThrow('window.atob("==")');
  • trunk/LayoutTests/platform/mac/fast/loader/user-stylesheet-fast-path-expected.txt

    r67642 r69072  
    22
    33PASS 100px
     4PASS 110px
     5PASS 120px
     6PASS 130px
    47PASS 140px
    58PASS 150px
  • trunk/LayoutTests/platform/mac/fast/loader/user-stylesheet-fast-path.html

    r67642 r69072  
    77    var testObjects = [
    88        {result:true,  size:"100px", url:"data:text/css;charset=utf-8;base64,Ym9keSB7Zm9udC1zaXplOiAxMDBweH0="},
     9        {result:true,  size:"110px", url:encodeURI("data:text/css;charset=utf-8;base64,                       Ym9keSB7Zm9udC1zaXplOiAxMTBweH0=                  ")},
     10        {result:true,  size:"120px", url:encodeURI("data:text/css;charset=utf-8;base64,\n \r \t Ym9k \t eSB7 \r Zm9ud \n \n C1zaXp \r lOiAxM \t jBweH0= \t \r \n")},
     11        {result:true,  size:"130px", url:encodeURI("data:text/css;charset=utf-8;base64,\u0059 \u006D \u0039 \u006B eSB7Zm9ud C1zaXplOiAxMzBwe \u0048 \u0030 \u003D")},
    912        {result:false, size:"140px", url:"data:text/css;charset=utf-8;base64,Ym9k$#eSB7Zm#9ud(C1zaXp)lOiAxNDBweH0="},
    1013        {result:false, size:"150px", url:"data:text/css;charset=utf-8;base64,Ym9ke%00SB7Z%20m9udC1z\n\taXplO#iAx%03NTBw%eH0="},
  • trunk/WebCore/ChangeLog

    r69071 r69072  
     12010-10-04  Patrick Gansterer  <paroga@paroga.com>
     2
     3        Reviewed by Darin Adler.
     4
     5        Add Base64DecodePolicy option at base64Decode()
     6        https://bugs.webkit.org/show_bug.cgi?id=41510
     7
     8        Add an option for ignoring characters in base64 data.
     9        This is necessary for decoding data urls.
     10
     11        Also add an overload to decode WebCore::String directly.
     12
     13        * page/DOMWindow.cpp:
     14        (WebCore::DOMWindow::atob):
     15        * page/Page.cpp:
     16        (WebCore::Page::userStyleSheetLocationChanged):
     17        * platform/text/Base64.cpp:
     18        (WebCore::base64Encode):
     19        (WebCore::base64Decode):
     20        (WebCore::base64DecodeInternal):
     21        * platform/text/Base64.h:
     22        (WebCore::):
     23
    1242010-10-04  Ryuan Choi  <bunhere@gmail.com>
    225
  • trunk/WebCore/page/DOMWindow.cpp

    r68440 r69072  
    994994    }
    995995
    996     Vector<char> in;
    997     in.append(encodedString.characters(), encodedString.length());
    998996    Vector<char> out;
    999 
    1000     if (!base64Decode(in, out)) {
     997    if (!base64Decode(encodedString, out, FailOnInvalidCharacter)) {
    1001998        ec = INVALID_CHARACTER_ERR;
    1002999        return String();
  • trunk/WebCore/page/Page.cpp

    r69053 r69072  
    636636    m_userStyleSheet = String();
    637637    m_userStyleSheetModificationTime = 0;
    638    
     638
    639639    // Data URLs with base64-encoded UTF-8 style sheets are common. We can process them
    640640    // synchronously and avoid using a loader.
    641641    if (url.protocolIs("data") && url.string().startsWith("data:text/css;charset=utf-8;base64,")) {
    642642        m_didLoadUserStyleSheet = true;
    643        
    644         const unsigned prefixLength = 35;
    645         Vector<char> encodedData(url.string().length() - prefixLength);
    646         for (unsigned i = prefixLength; i < url.string().length(); ++i)
    647             encodedData[i - prefixLength] = static_cast<char>(url.string()[i]);
    648643
    649644        Vector<char> styleSheetAsUTF8;
    650         if (base64Decode(encodedData, styleSheetAsUTF8))
     645        if (base64Decode(decodeURLEscapeSequences(url.string().substring(35)), styleSheetAsUTF8, IgnoreWhitespace))
    651646            m_userStyleSheet = String::fromUTF8(styleSheetAsUTF8.data(), styleSheetAsUTF8.size());
    652647    }
    653    
     648
    654649    for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNext()) {
    655650        if (frame->document())
  • trunk/WebCore/platform/text/Base64.cpp

    r55633 r69072  
    33   Copyright (C) 2006 Alexey Proskuryakov <ap@webkit.org>
    44   Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
     5   Copyright (C) 2010 Patrick Gansterer <paroga@paroga.com>
    56
    67   This program is free software; you can redistribute it and/or modify
     
    2627#include <limits.h>
    2728#include <wtf/StringExtras.h>
     29#include <wtf/text/WTFString.h>
    2830
    2931namespace WebCore {
     
    7173
    7274    // If the input string is pathologically large, just return nothing.
    73     // Note: Keep this in sync with the "out_len" computation below.
     75    // Note: Keep this in sync with the "outLength" computation below.
    7476    // Rather than being perfectly precise, this is a bit conservative.
    7577    const unsigned maxInputBufferSize = UINT_MAX / 77 * 76 / 4 * 3 - 2;
     
    8082    unsigned didx = 0;
    8183
    82     unsigned out_len = ((len + 2) / 3) * 4;
     84    unsigned outLength = ((len + 2) / 3) * 4;
    8385
    8486    // Deal with the 76 character per line limit specified in RFC 2045.
    85     insertLFs = (insertLFs && out_len > 76);
     87    insertLFs = (insertLFs && outLength > 76);
    8688    if (insertLFs)
    87         out_len += ((out_len - 1) / 76);
     89        outLength += ((outLength - 1) / 76);
    8890
    8991    int count = 0;
    90     out.grow(out_len);
     92    out.grow(outLength);
    9193
    9294    // 3-byte to 4-byte conversion + 0-63 to ascii printable conversion
     
    9496        while (sidx < len - 2) {
    9597            if (insertLFs) {
    96                 if (count && (count % 76) == 0)
     98                if (count && !(count % 76))
    9799                    out[didx++] = '\n';
    98100                count += 4;
     
    107109
    108110    if (sidx < len) {
    109         if (insertLFs && (count > 0) && (count % 76) == 0)
     111        if (insertLFs && (count > 0) && !(count % 76))
    110112           out[didx++] = '\n';
    111113
     
    125127}
    126128
    127 bool base64Decode(const Vector<char>& in, Vector<char>& out)
     129bool base64Decode(const Vector<char>& in, Vector<char>& out, Base64DecodePolicy policy)
    128130{
    129131    out.clear();
     
    133135        return false;
    134136
    135     return base64Decode(in.data(), in.size(), out);
    136 }
    137 
    138 bool base64Decode(const char* data, unsigned len, Vector<char>& out)
     137    return base64Decode(in.data(), in.size(), out, policy);
     138}
     139
     140template<typename T>
     141static inline bool base64DecodeInternal(const T* data, unsigned len, Vector<char>& out, Base64DecodePolicy policy)
    139142{
    140143    out.clear();
    141     if (len == 0)
     144    if (!len)
    142145        return true;
    143146
    144     while (len && data[len-1] == '=')
    145         --len;
    146 
    147147    out.grow(len);
     148
     149    bool sawEqualsSign = false;
     150    unsigned outLength = 0;
    148151    for (unsigned idx = 0; idx < len; idx++) {
    149         unsigned char ch = data[idx];
    150         if ((ch > 47 && ch < 58) || (ch > 64 && ch < 91) || (ch > 96 && ch < 123) || ch == '+' || ch == '/' || ch == '=')
    151             out[idx] = base64DecMap[ch];
    152         else
     152        unsigned ch = data[idx];
     153        if (ch == '=')
     154            sawEqualsSign = true;
     155        else if (('0' <= ch && ch <= '9') || ('A' <= ch && ch <= 'Z') || ('a' <= ch && ch <= 'z') || ch == '+' || ch == '/') {
     156            if (sawEqualsSign)
     157                return false;
     158            out[outLength] = base64DecMap[ch];
     159            outLength++;
     160        } else if (policy == FailOnInvalidCharacter || (policy == IgnoreWhitespace && !isSpaceOrNewline(ch)))
    153161            return false;
    154162    }
    155163
     164    if (!outLength)
     165        return !sawEqualsSign;
     166
     167    // Valid data is (n * 4 + [0,2,3]) characters long.
     168    if ((outLength % 4) == 1)
     169        return false;
     170   
    156171    // 4-byte to 3-byte conversion
    157     unsigned outLen = len - ((len + 3) / 4);
    158     if (!outLen || ((outLen + 2) / 3) * 4 < len)
     172    outLength -= (outLength + 3) / 4;
     173    if (!outLength)
    159174        return false;
    160175
    161176    unsigned sidx = 0;
    162177    unsigned didx = 0;
    163     if (outLen > 1) {
    164         while (didx < outLen - 2) {
     178    if (outLength > 1) {
     179        while (didx < outLength - 2) {
    165180            out[didx] = (((out[sidx] << 2) & 255) | ((out[sidx + 1] >> 4) & 003));
    166181            out[didx + 1] = (((out[sidx + 1] << 4) & 255) | ((out[sidx + 2] >> 2) & 017));
     
    171186    }
    172187
    173     if (didx < outLen)
     188    if (didx < outLength)
    174189        out[didx] = (((out[sidx] << 2) & 255) | ((out[sidx + 1] >> 4) & 003));
    175190
    176     if (++didx < outLen)
     191    if (++didx < outLength)
    177192        out[didx] = (((out[sidx + 1] << 4) & 255) | ((out[sidx + 2] >> 2) & 017));
    178193
    179     if (outLen < out.size())
    180         out.shrink(outLen);
     194    if (outLength < out.size())
     195        out.shrink(outLength);
    181196
    182197    return true;
    183198}
    184199
    185 }
     200bool base64Decode(const char* data, unsigned len, Vector<char>& out, Base64DecodePolicy policy)
     201{
     202    return base64DecodeInternal<char>(data, len, out, policy);
     203}
     204
     205bool base64Decode(const String& in, Vector<char>& out, Base64DecodePolicy policy)
     206{
     207    return base64DecodeInternal<UChar>(in.characters(), in.length(), out, policy);
     208}
     209
     210} // namespace WebCore
  • trunk/WebCore/platform/text/Base64.h

    r54616 r69072  
    11/*
    2  * Copyright (C) 2006 Alexey Proskuryakov (ap@webkit.org)
     2 * Copyright (C) 2006 Alexey Proskuryakov <ap@webkit.org>
     3 * Copyright (C) 2010 Patrick Gansterer <paroga@paroga.com>
    34 *
    45 * Redistribution and use in source and binary forms, with or without
     
    2728#define Base64_h
    2829
     30#include <wtf/Forward.h>
    2931#include <wtf/Vector.h>
    3032
    3133namespace WebCore {
    3234
     35enum Base64DecodePolicy { FailOnInvalidCharacter, IgnoreWhitespace, IgnoreInvalidCharacters };
     36
    3337void base64Encode(const Vector<char>&, Vector<char>&, bool insertLFs = false);
    3438void base64Encode(const char*, unsigned, Vector<char>&, bool insertLFs = false);
    3539
    36 // this decoder is not general purpose - it returns an error if it encounters a linefeed, as needed for window.atob
    37 bool base64Decode(const Vector<char>&, Vector<char>&);
    38 bool base64Decode(const char*, unsigned, Vector<char>&);
     40bool base64Decode(const String&, Vector<char>&, Base64DecodePolicy = FailOnInvalidCharacter);
     41bool base64Decode(const Vector<char>&, Vector<char>&, Base64DecodePolicy = FailOnInvalidCharacter);
     42bool base64Decode(const char*, unsigned, Vector<char>&, Base64DecodePolicy = FailOnInvalidCharacter);
    3943
    4044}
Note: See TracChangeset for help on using the changeset viewer.