зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1353684 - nsIFileInputStream must return NS_ERROR_NOT_FOUND if Deserialize() fails, r=smaug
This commit is contained in:
Родитель
54c9498baf
Коммит
e1cf92c22c
|
@ -158,7 +158,7 @@ onmessage = function(message) {
|
|||
expectedTestCount++;
|
||||
|
||||
r = new FileReader();
|
||||
r.onload = getLoadHandler(convertToDataURL(""), 0, "empt binary string reading");
|
||||
r.onload = getLoadHandler(convertToDataURL(""), 0, "empty binary string reading");
|
||||
r.readAsDataURL(emptyFile);
|
||||
expectedTestCount++;
|
||||
|
||||
|
|
|
@ -40,7 +40,8 @@ using mozilla::Some;
|
|||
nsFileStreamBase::nsFileStreamBase()
|
||||
: mFD(nullptr)
|
||||
, mBehaviorFlags(0)
|
||||
, mDeferredOpen(false)
|
||||
, mState(eUnitialized)
|
||||
, mErrorValue(NS_ERROR_FAILURE)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -59,9 +60,6 @@ nsFileStreamBase::Seek(int32_t whence, int64_t offset)
|
|||
nsresult rv = DoPendingOpen();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (mFD == nullptr)
|
||||
return NS_BASE_STREAM_CLOSED;
|
||||
|
||||
int64_t cnt = PR_Seek64(mFD, offset, (PRSeekWhence)whence);
|
||||
if (cnt == int64_t(-1)) {
|
||||
return NS_ErrorAccordingToNSPR();
|
||||
|
@ -75,9 +73,6 @@ nsFileStreamBase::Tell(int64_t *result)
|
|||
nsresult rv = DoPendingOpen();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (mFD == nullptr)
|
||||
return NS_BASE_STREAM_CLOSED;
|
||||
|
||||
int64_t cnt = PR_Seek64(mFD, 0, PR_SEEK_CUR);
|
||||
if (cnt == int64_t(-1)) {
|
||||
return NS_ErrorAccordingToNSPR();
|
||||
|
@ -92,9 +87,6 @@ nsFileStreamBase::SetEOF()
|
|||
nsresult rv = DoPendingOpen();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (mFD == nullptr)
|
||||
return NS_BASE_STREAM_CLOSED;
|
||||
|
||||
#if defined(XP_UNIX) || defined(XP_BEOS)
|
||||
// Some system calls require an EOF offset.
|
||||
int64_t offset;
|
||||
|
@ -125,10 +117,6 @@ nsFileStreamBase::GetSize(int64_t* _retval)
|
|||
nsresult rv = DoPendingOpen();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!mFD) {
|
||||
return NS_BASE_STREAM_CLOSED;
|
||||
}
|
||||
|
||||
PRFileInfo64 info;
|
||||
if (PR_GetOpenFileInfo64(mFD, &info) == PR_FAILURE) {
|
||||
return NS_BASE_STREAM_OSERROR;
|
||||
|
@ -145,10 +133,6 @@ nsFileStreamBase::GetLastModified(int64_t* _retval)
|
|||
nsresult rv = DoPendingOpen();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!mFD) {
|
||||
return NS_BASE_STREAM_CLOSED;
|
||||
}
|
||||
|
||||
PRFileInfo64 info;
|
||||
if (PR_GetOpenFileInfo64(mFD, &info) == PR_FAILURE) {
|
||||
return NS_BASE_STREAM_OSERROR;
|
||||
|
@ -169,13 +153,7 @@ NS_IMETHODIMP
|
|||
nsFileStreamBase::GetFileDescriptor(PRFileDesc** _retval)
|
||||
{
|
||||
nsresult rv = DoPendingOpen();
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (!mFD) {
|
||||
return NS_BASE_STREAM_CLOSED;
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
*_retval = mFD;
|
||||
return NS_OK;
|
||||
|
@ -191,6 +169,7 @@ nsFileStreamBase::Close()
|
|||
if (PR_Close(mFD) == PR_FAILURE)
|
||||
rv = NS_BASE_STREAM_OSERROR;
|
||||
mFD = nullptr;
|
||||
mState = eClosed;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
@ -201,10 +180,6 @@ nsFileStreamBase::Available(uint64_t* aResult)
|
|||
nsresult rv = DoPendingOpen();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!mFD) {
|
||||
return NS_BASE_STREAM_CLOSED;
|
||||
}
|
||||
|
||||
// PR_Available with files over 4GB returns an error, so we have to
|
||||
// use the 64-bit version of PR_Available.
|
||||
int64_t avail = PR_Available64(mFD);
|
||||
|
@ -221,18 +196,15 @@ nsresult
|
|||
nsFileStreamBase::Read(char* aBuf, uint32_t aCount, uint32_t* aResult)
|
||||
{
|
||||
nsresult rv = DoPendingOpen();
|
||||
if (rv == NS_ERROR_FILE_NOT_FOUND) {
|
||||
// Don't warn if this is just a deferred file not found.
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (!mFD) {
|
||||
if (rv == NS_BASE_STREAM_CLOSED) {
|
||||
*aResult = 0;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
int32_t bytesRead = PR_Read(mFD, aBuf, aCount);
|
||||
if (bytesRead == -1) {
|
||||
return NS_ErrorAccordingToNSPR();
|
||||
|
@ -267,9 +239,6 @@ nsFileStreamBase::Flush(void)
|
|||
nsresult rv = DoPendingOpen();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (mFD == nullptr)
|
||||
return NS_BASE_STREAM_CLOSED;
|
||||
|
||||
int32_t cnt = PR_Sync(mFD);
|
||||
if (cnt == -1) {
|
||||
return NS_ErrorAccordingToNSPR();
|
||||
|
@ -283,9 +252,6 @@ nsFileStreamBase::Write(const char *buf, uint32_t count, uint32_t *result)
|
|||
nsresult rv = DoPendingOpen();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (mFD == nullptr)
|
||||
return NS_BASE_STREAM_CLOSED;
|
||||
|
||||
int32_t cnt = PR_Write(mFD, buf, count);
|
||||
if (cnt == -1) {
|
||||
return NS_ErrorAccordingToNSPR();
|
||||
|
@ -331,7 +297,7 @@ nsFileStreamBase::MaybeOpen(nsIFile* aFile, int32_t aIoFlags,
|
|||
mOpenParams.localFile = do_QueryInterface(file);
|
||||
NS_ENSURE_TRUE(mOpenParams.localFile, NS_ERROR_UNEXPECTED);
|
||||
|
||||
mDeferredOpen = true;
|
||||
mState = eDeferredOpen;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -346,12 +312,13 @@ void
|
|||
nsFileStreamBase::CleanUpOpen()
|
||||
{
|
||||
mOpenParams.localFile = nullptr;
|
||||
mDeferredOpen = false;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsFileStreamBase::DoOpen()
|
||||
{
|
||||
MOZ_ASSERT(mState == eDeferredOpen || mState == eUnitialized ||
|
||||
mState == eClosed);
|
||||
NS_ASSERTION(!mFD, "Already have a file descriptor!");
|
||||
NS_ASSERTION(mOpenParams.localFile, "Must have a file to open");
|
||||
|
||||
|
@ -375,9 +342,14 @@ nsFileStreamBase::DoOpen()
|
|||
}
|
||||
|
||||
CleanUpOpen();
|
||||
if (NS_FAILED(rv))
|
||||
if (NS_FAILED(rv)) {
|
||||
mState = eError;
|
||||
mErrorValue = rv;
|
||||
return rv;
|
||||
}
|
||||
|
||||
mFD = fd;
|
||||
mState = eOpened;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -385,13 +357,31 @@ nsFileStreamBase::DoOpen()
|
|||
nsresult
|
||||
nsFileStreamBase::DoPendingOpen()
|
||||
{
|
||||
if (!mDeferredOpen) {
|
||||
switch (mState) {
|
||||
case eUnitialized:
|
||||
MOZ_CRASH("This should not happen.");
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
case eDeferredOpen:
|
||||
return DoOpen();
|
||||
|
||||
case eOpened:
|
||||
MOZ_ASSERT(mFD);
|
||||
return NS_OK;
|
||||
|
||||
case eClosed:
|
||||
MOZ_ASSERT(!mFD);
|
||||
return NS_BASE_STREAM_CLOSED;
|
||||
|
||||
case eError:
|
||||
return mErrorValue;
|
||||
}
|
||||
|
||||
return DoOpen();
|
||||
MOZ_CRASH("Invalid mState value.");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsFileInputStream
|
||||
|
||||
|
@ -475,9 +465,11 @@ nsFileInputStream::Init(nsIFile* aFile, int32_t aIOFlags, int32_t aPerm,
|
|||
int32_t aBehaviorFlags)
|
||||
{
|
||||
NS_ENSURE_TRUE(!mFD, NS_ERROR_ALREADY_INITIALIZED);
|
||||
NS_ENSURE_TRUE(!mDeferredOpen, NS_ERROR_ALREADY_INITIALIZED);
|
||||
NS_ENSURE_TRUE(mState == eUnitialized || mState == eClosed,
|
||||
NS_ERROR_ALREADY_INITIALIZED);
|
||||
|
||||
mBehaviorFlags = aBehaviorFlags;
|
||||
mState = eUnitialized;
|
||||
|
||||
mFile = aFile;
|
||||
mIOFlags = aIOFlags;
|
||||
|
@ -550,12 +542,15 @@ nsresult
|
|||
nsFileInputStream::SeekInternal(int32_t aWhence, int64_t aOffset, bool aClearBuf)
|
||||
{
|
||||
nsresult rv = DoPendingOpen();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (rv != NS_OK && rv != NS_BASE_STREAM_CLOSED) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (aClearBuf) {
|
||||
mLineBuffer = nullptr;
|
||||
}
|
||||
if (!mFD) {
|
||||
|
||||
if (rv == NS_BASE_STREAM_CLOSED) {
|
||||
if (mBehaviorFlags & REOPEN_ON_REWIND) {
|
||||
rv = Open(mFile, mIOFlags, mPerm);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
@ -593,7 +588,8 @@ nsFileInputStream::Serialize(InputStreamParams& aParams,
|
|||
{
|
||||
FileInputStreamParams params;
|
||||
|
||||
if (NS_SUCCEEDED(DoPendingOpen()) && mFD) {
|
||||
if (NS_SUCCEEDED(DoPendingOpen())) {
|
||||
MOZ_ASSERT(mFD);
|
||||
FileHandleType fd = FileHandleType(PR_FileDesc2NativeHandle(mFD));
|
||||
NS_ASSERTION(fd, "This should never be null!");
|
||||
|
||||
|
@ -627,7 +623,7 @@ nsFileInputStream::Deserialize(const InputStreamParams& aParams,
|
|||
const FileDescriptorArray& aFileDescriptors)
|
||||
{
|
||||
NS_ASSERTION(!mFD, "Already have a file descriptor?!");
|
||||
NS_ASSERTION(!mDeferredOpen, "Deferring open?!");
|
||||
NS_ASSERTION(mState == nsFileStreamBase::eUnitialized, "Deferring open?!");
|
||||
NS_ASSERTION(!mFile, "Should never have a file here!");
|
||||
NS_ASSERTION(!mPerm, "This should always be 0!");
|
||||
|
||||
|
@ -657,6 +653,10 @@ nsFileInputStream::Deserialize(const InputStreamParams& aParams,
|
|||
return false;
|
||||
}
|
||||
mFD = fileDesc;
|
||||
mState = eOpened;
|
||||
} else {
|
||||
mState = eError;
|
||||
mErrorValue = NS_ERROR_FILE_NOT_FOUND;
|
||||
}
|
||||
|
||||
mBehaviorFlags = params.behaviorFlags();
|
||||
|
@ -709,9 +709,11 @@ nsFileOutputStream::Init(nsIFile* file, int32_t ioFlags, int32_t perm,
|
|||
int32_t behaviorFlags)
|
||||
{
|
||||
NS_ENSURE_TRUE(mFD == nullptr, NS_ERROR_ALREADY_INITIALIZED);
|
||||
NS_ENSURE_TRUE(!mDeferredOpen, NS_ERROR_ALREADY_INITIALIZED);
|
||||
NS_ENSURE_TRUE(mState == eUnitialized || mState == eClosed,
|
||||
NS_ERROR_ALREADY_INITIALIZED);
|
||||
|
||||
mBehaviorFlags = behaviorFlags;
|
||||
mState = eUnitialized;
|
||||
|
||||
if (ioFlags == -1)
|
||||
ioFlags = PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE;
|
||||
|
@ -911,9 +913,11 @@ nsFileStream::Init(nsIFile* file, int32_t ioFlags, int32_t perm,
|
|||
int32_t behaviorFlags)
|
||||
{
|
||||
NS_ENSURE_TRUE(mFD == nullptr, NS_ERROR_ALREADY_INITIALIZED);
|
||||
NS_ENSURE_TRUE(!mDeferredOpen, NS_ERROR_ALREADY_INITIALIZED);
|
||||
NS_ENSURE_TRUE(mState == eUnitialized || mState == eClosed,
|
||||
NS_ERROR_ALREADY_INITIALIZED);
|
||||
|
||||
mBehaviorFlags = behaviorFlags;
|
||||
mState = eUnitialized;
|
||||
|
||||
if (ioFlags == -1)
|
||||
ioFlags = PR_RDWR;
|
||||
|
|
|
@ -55,10 +55,19 @@ protected:
|
|||
*/
|
||||
int32_t mBehaviorFlags;
|
||||
|
||||
/**
|
||||
* Whether we have a pending open (see DEFER_OPEN in the IDL file).
|
||||
*/
|
||||
bool mDeferredOpen;
|
||||
enum {
|
||||
// This is the default value. It will be changed by Deserialize or Init.
|
||||
eUnitialized,
|
||||
// The opening has been deferred. See DEFER_OPEN.
|
||||
eDeferredOpen,
|
||||
// The file has been opened. mFD is not null.
|
||||
eOpened,
|
||||
// The file has been closed. mFD is null.
|
||||
eClosed,
|
||||
// Something bad happen in the Open() or in Deserialize(). The actual
|
||||
// error value is stored in mErrorValue.
|
||||
eError
|
||||
} mState;
|
||||
|
||||
struct OpenParams {
|
||||
nsCOMPtr<nsIFile> localFile;
|
||||
|
@ -71,6 +80,8 @@ protected:
|
|||
*/
|
||||
OpenParams mOpenParams;
|
||||
|
||||
nsresult mErrorValue;
|
||||
|
||||
/**
|
||||
* Prepares the data we need to open the file, and either does the open now
|
||||
* by calling DoOpen(), or leaves it to be opened later by a call to
|
||||
|
@ -93,8 +104,9 @@ protected:
|
|||
virtual nsresult DoOpen();
|
||||
|
||||
/**
|
||||
* If there is a pending open, do it now. It's important for this to be
|
||||
* inline since we do it in almost every stream API call.
|
||||
* Based on mState, this method does the opening, return an error, or do
|
||||
* nothing. If the return value is not NS_OK, please, return it back to the
|
||||
* callee.
|
||||
*/
|
||||
inline nsresult DoPendingOpen();
|
||||
};
|
||||
|
|
Загрузка…
Ссылка в новой задаче