Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e82dc420 authored by Patrick Scott's avatar Patrick Scott
Browse files

Parse the base64 data before creating the data stream.

This will ensure that we do not parse the data in chunks when passing it to the
LoadListener. Decoding in chunks can lead to incomplete sequences which will
lead to a failed decode.

Check for a cancelled LoadListener in StreamLoader and stop the load. This is
just a shortcut for downloaded or failed resources.

Cleanup some of the LoadListener code around resetting a few member variables.
Reset them in the status callback since that indicates a new response from the
server (or StreamLoader).
parent 42fba356
Loading
Loading
Loading
Loading
+13 −16
Original line number Original line Diff line number Diff line
@@ -16,12 +16,10 @@


package android.webkit;
package android.webkit;


import org.apache.http.protocol.HTTP;

import android.net.http.Headers;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayInputStream;


import org.apache.harmony.luni.util.Base64;

/**
/**
 * This class is a concrete implementation of StreamLoader that uses the
 * This class is a concrete implementation of StreamLoader that uses the
 * content supplied as a URL as the source for the stream. The mimetype
 * content supplied as a URL as the source for the stream. The mimetype
@@ -30,8 +28,6 @@ import java.io.ByteArrayInputStream;
 */
 */
class DataLoader extends StreamLoader {
class DataLoader extends StreamLoader {


    private String mContentType;  // Content mimetype, if supplied in URL

    /**
    /**
     * Constructor uses the dataURL as the source for an InputStream
     * Constructor uses the dataURL as the source for an InputStream
     * @param dataUrl data: URL string optionally containing a mimetype
     * @param dataUrl data: URL string optionally containing a mimetype
@@ -41,16 +37,20 @@ class DataLoader extends StreamLoader {
        super(loadListener);
        super(loadListener);


        String url = dataUrl.substring("data:".length());
        String url = dataUrl.substring("data:".length());
        String content;
        byte[] data = null;
        int commaIndex = url.indexOf(',');
        int commaIndex = url.indexOf(',');
        if (commaIndex != -1) {
        if (commaIndex != -1) {
            mContentType = url.substring(0, commaIndex);
            String contentType = url.substring(0, commaIndex);
            content = url.substring(commaIndex + 1);
            data = url.substring(commaIndex + 1).getBytes();
            loadListener.parseContentTypeHeader(contentType);
            if (loadListener.transferEncoding().equals("base64")) {
                data = Base64.decode(data);
            }
        } else {
        } else {
            content = url;
            data = url.getBytes();
        }
        }
        mDataStream = new ByteArrayInputStream(content.getBytes());
        mDataStream = new ByteArrayInputStream(data);
        mContentLength = content.length();
        mContentLength = data.length;
    }
    }


    @Override
    @Override
@@ -60,10 +60,7 @@ class DataLoader extends StreamLoader {
    }
    }


    @Override
    @Override
    protected void buildHeaders(Headers headers) {
    protected void buildHeaders(android.net.http.Headers h) {
        if (mContentType != null) {
            headers.setContentType(mContentType);
        }
    }
    }


    /**
    /**
+8 −20
Original line number Original line Diff line number Diff line
@@ -43,8 +43,6 @@ import java.util.Vector;
import java.util.regex.Pattern;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
import java.util.regex.Matcher;


import org.apache.commons.codec.binary.Base64;

class LoadListener extends Handler implements EventHandler {
class LoadListener extends Handler implements EventHandler {


    private static final String LOGTAG = "webkit";
    private static final String LOGTAG = "webkit";
@@ -140,8 +138,6 @@ class LoadListener extends Handler implements EventHandler {
        mBrowserFrame = frame;
        mBrowserFrame = frame;
        setUrl(url);
        setUrl(url);
        mNativeLoader = nativeLoader;
        mNativeLoader = nativeLoader;
        mMimeType = "";
        mEncoding = "";
        mSynchronous = synchronous;
        mSynchronous = synchronous;
        if (synchronous) {
        if (synchronous) {
            mMessageQueue = new Vector<Message>();
            mMessageQueue = new Vector<Message>();
@@ -292,8 +288,6 @@ class LoadListener extends Handler implements EventHandler {
    private void handleHeaders(Headers headers) {
    private void handleHeaders(Headers headers) {
        if (mCancelled) return;
        if (mCancelled) return;
        mHeaders = headers;
        mHeaders = headers;
        mMimeType = "";
        mEncoding = "";


        ArrayList<String> cookies = headers.getSetCookie();
        ArrayList<String> cookies = headers.getSetCookie();
        for (int i = 0; i < cookies.size(); ++i) {
        for (int i = 0; i < cookies.size(); ++i) {
@@ -442,6 +436,9 @@ class LoadListener extends Handler implements EventHandler {
        status.put("reason", reasonPhrase);
        status.put("reason", reasonPhrase);
        // New status means new data. Clear the old.
        // New status means new data. Clear the old.
        mDataBuilder.clear();
        mDataBuilder.clear();
        mMimeType = "";
        mEncoding = "";
        mTransferEncoding = "";
        sendMessageInternal(obtainMessage(MSG_STATUS, status));
        sendMessageInternal(obtainMessage(MSG_STATUS, status));
    }
    }


@@ -517,19 +514,6 @@ class LoadListener extends Handler implements EventHandler {
            Log.v(LOGTAG, "LoadListener.data(): url: " + url());
            Log.v(LOGTAG, "LoadListener.data(): url: " + url());
        }
        }


        // Decode base64 data
        // Note: It's fine that we only decode base64 here and not in the other
        // data call because the only caller of the stream version is not
        // base64 encoded.
        if ("base64".equals(mTransferEncoding)) {
            if (length < data.length) {
                byte[] trimmedData = new byte[length];
                System.arraycopy(data, 0, trimmedData, 0, length);
                data = trimmedData;
            }
            data = Base64.decodeBase64(data);
            length = data.length;
        }
        // Synchronize on mData because commitLoad may write mData to WebCore
        // Synchronize on mData because commitLoad may write mData to WebCore
        // and we don't want to replace mData or mDataLength at the same time
        // and we don't want to replace mData or mDataLength at the same time
        // as a write.
        // as a write.
@@ -904,6 +888,10 @@ class LoadListener extends Handler implements EventHandler {
        return mMimeType;
        return mMimeType;
    }
    }


    String transferEncoding() {
        return mTransferEncoding;
    }

    /*
    /*
     * Return the size of the content being downloaded. This represents the
     * Return the size of the content being downloaded. This represents the
     * full content size, even under the situation where the download has been
     * full content size, even under the situation where the download has been
@@ -1198,7 +1186,7 @@ class LoadListener extends Handler implements EventHandler {
    private static final Pattern CONTENT_TYPE_PATTERN =
    private static final Pattern CONTENT_TYPE_PATTERN =
            Pattern.compile("^((?:[xX]-)?[a-zA-Z\\*]+/[\\w\\+\\*-]+[\\.[\\w\\+-]+]*)$");
            Pattern.compile("^((?:[xX]-)?[a-zA-Z\\*]+/[\\w\\+\\*-]+[\\.[\\w\\+-]+]*)$");


    private void parseContentTypeHeader(String contentType) {
    /* package */ void parseContentTypeHeader(String contentType) {
        if (WebView.LOGV_ENABLED) {
        if (WebView.LOGV_ENABLED) {
            Log.v(LOGTAG, "LoadListener.parseContentTypeHeader: " +
            Log.v(LOGTAG, "LoadListener.parseContentTypeHeader: " +
                    "contentType: " + contentType);
                    "contentType: " + contentType);
+5 −1
Original line number Original line Diff line number Diff line
@@ -102,7 +102,7 @@ abstract class StreamLoader extends Handler {
                // to pass data to the loader
                // to pass data to the loader
                mData = new byte[8192];
                mData = new byte[8192];
                sendHeaders();
                sendHeaders();
                while (!sendData());
                while (!sendData() && !mHandler.cancelled());
                closeStreamAndSendEndData();
                closeStreamAndSendEndData();
                mHandler.loadSynchronousMessages();
                mHandler.loadSynchronousMessages();
            }
            }
@@ -116,6 +116,10 @@ abstract class StreamLoader extends Handler {
        if (WebView.DEBUG && mHandler.isSynchronous()) {
        if (WebView.DEBUG && mHandler.isSynchronous()) {
            throw new AssertionError();
            throw new AssertionError();
        }
        }
        if (mHandler.cancelled()) {
            closeStreamAndSendEndData();
            return;
        }
        switch(msg.what) {
        switch(msg.what) {
            case MSG_STATUS:
            case MSG_STATUS:
                if (setupStreamAndSendStatus()) {
                if (setupStreamAndSendStatus()) {