From 72b138b1d82325d1f58d3d93a505f95ef665df16 Mon Sep 17 00:00:00 2001 From: Barret Rennie Date: Wed, 17 Nov 2021 00:28:58 +0000 Subject: [PATCH] Bug 1723082 - Support reading files > INT32_MAX in IOUtils r=Gijs Previously, if you attempted to read a file greater than INT32_MAX in size, we would either fail to read the file (on release) or crash (on debug). This is due to the implementation of _PR_MD_READ accepting an int32_t of bytes to read instead of a uint32_t, which nsFileStream::Read accepts and passes on. Differential Revision: https://phabricator.services.mozilla.com/D131161 --- dom/chrome-webidl/IOUtils.webidl | 8 +++++++- dom/docs/ioutils_migration.md | 3 +++ dom/system/IOUtils.cpp | 6 +++++- 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/dom/chrome-webidl/IOUtils.webidl b/dom/chrome-webidl/IOUtils.webidl index fb662a879b69..9eeeed31cc18 100644 --- a/dom/chrome-webidl/IOUtils.webidl +++ b/dom/chrome-webidl/IOUtils.webidl @@ -24,7 +24,9 @@ [ChromeOnly, Exposed=(Window, Worker)] namespace IOUtils { /** - * Reads up to |maxBytes| of the file at |path| according to |opts|. + * Reads up to |opts.maxBytes| of the file at |path| according to |opts|. + * + * NB: The maximum file size that can be read is UINT32_MAX. * * @param path An absolute file path. * @@ -36,6 +38,8 @@ namespace IOUtils { * Reads the UTF-8 text file located at |path| and returns the decoded * contents as a |DOMString|. * + * NB: The maximum file size that can be read is UINT32_MAX. + * * @param path An absolute file path. * * @return Resolves with the file contents encoded as a string, otherwise @@ -46,6 +50,8 @@ namespace IOUtils { * Read the UTF-8 text file located at |path| and return the contents * parsed as JSON into a JS value. * + * NB: The maximum file size that can be read is UINT32_MAX. + * * @param path An absolute path. * * @return Resolves with the contents of the file parsed as JSON. diff --git a/dom/docs/ioutils_migration.md b/dom/docs/ioutils_migration.md index 07d3f749b3e2..32c0b1131d82 100644 --- a/dom/docs/ioutils_migration.md +++ b/dom/docs/ioutils_migration.md @@ -106,6 +106,9 @@ The following is a detailed comparison with examples of the methods and options `IOUtils` provides the following methods to read data from a file. Like `OS.File`, they accept an `options` dictionary. +Note: The maximum file size that can be read is `UINT32_MAX` bytes. Attempting +to read a file larger will result in a `NotReadableError`. + ```idl Promise read(DOMString path, ...); diff --git a/dom/system/IOUtils.cpp b/dom/system/IOUtils.cpp index 526e0e7ebcaa..26580bd95d3a 100644 --- a/dom/system/IOUtils.cpp +++ b/dom/system/IOUtils.cpp @@ -896,9 +896,13 @@ Result IOUtils::ReadSync( // Read the file from disk. uint32_t totalRead = 0; while (totalRead != bufSize) { + // Read no more than INT32_MAX on each call to stream->Read, otherwise it + // returns an error. + uint32_t bytesToReadThisChunk = + std::min(bufSize - totalRead, INT32_MAX); uint32_t bytesRead = 0; if (nsresult rv = - stream->Read(toRead.Elements(), bufSize - totalRead, &bytesRead); + stream->Read(toRead.Elements(), bytesToReadThisChunk, &bytesRead); NS_FAILED(rv)) { return Err(IOError(rv).WithMessage( "Encountered an unexpected error while reading file(%s)",