Bug 296795: ZipReader doesn't handle non-ASCII characters r=taras

This commit is contained in:
Wolfgang Germund 2011-09-28 16:14:45 -07:00
Родитель 5988d33707
Коммит ca97ac6ac0
11 изменённых файлов: 109 добавлений и 69 удалений

Просмотреть файл

@ -2974,7 +2974,7 @@ nsScriptSecurityManager::SetCanEnableCapability(const nsACString& certFingerprin
rv = systemCertZip->Open(systemCertFile);
if (NS_SUCCEEDED(rv))
{
rv = systemCertZip->GetCertificatePrincipal(nsnull,
rv = systemCertZip->GetCertificatePrincipal(EmptyCString(),
getter_AddRefs(mSystemCertificate));
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
}

Просмотреть файл

@ -91,7 +91,7 @@ interface nsIZipEntry : nsISupports
readonly attribute boolean isSynthetic;
};
[scriptable, uuid(7bb925d6-833a-486c-8ef2-9bc15c670a60)]
[scriptable, uuid(8fbf5023-3827-4fbc-a464-5db546e7f747)]
interface nsIZipReader : nsISupports
{
/**
@ -104,7 +104,7 @@ interface nsIZipReader : nsISupports
/**
* Opens a zip file inside a zip file for reading.
*/
void openInner(in nsIZipReader zipReader, in string zipEntry);
void openInner(in nsIZipReader zipReader, in AUTF8String zipEntry);
/**
* The file that represents the zip with which this zip reader was
@ -121,10 +121,11 @@ interface nsIZipReader : nsISupports
/**
* Tests the integrity of the archive by performing a CRC check
* on each item expanded into memory. If an entry is specified
* the integrity of only that item is tested. If NULL is passed
* in the integrity of all items in the archive are tested.
* the integrity of only that item is tested. If null (javascript)
* or EmptyCString() (c++) is passed in the integrity of all items
* in the archive are tested.
*/
void test(in string aEntryName);
void test(in AUTF8String aEntryName);
/**
* Extracts a zip entry into a local file specified by outFile.
@ -133,12 +134,12 @@ interface nsIZipReader : nsISupports
* If the entry is a directory, the directory will be extracted
* non-recursively.
*/
void extract(in string zipEntry, in nsIFile outFile);
void extract(in AUTF8String zipEntry, in nsIFile outFile);
/**
* Returns a nsIZipEntry describing a specified zip entry.
*/
nsIZipEntry getEntry(in string zipEntry);
nsIZipEntry getEntry(in AUTF8String zipEntry);
/**
* Checks whether the zipfile contains an entry specified by entryName.
@ -150,7 +151,8 @@ interface nsIZipReader : nsISupports
*
* @param aPattern
* A regular expression used to find matching entries in the zip file.
* Set this parameter to null to get all entries; otherwise, use the
* Set this parameter to null (javascript) or EmptyCString() (c++) or "*"
* to get all entries; otherwise, use the
* following syntax:
*
* o * matches anything
@ -187,14 +189,14 @@ interface nsIZipReader : nsISupports
* @throws NS_ERROR_ILLEGAL_VALUE on many but not all invalid aPattern
* values.
*/
nsIUTF8StringEnumerator findEntries(in string aPattern);
nsIUTF8StringEnumerator findEntries(in AUTF8String aPattern);
/**
* Returns an input stream containing the contents of the specified zip
* entry.
* @param zipEntry the name of the entry to open the stream from
*/
nsIInputStream getInputStream(in string zipEntry);
nsIInputStream getInputStream(in AUTF8String zipEntry);
/**
* Returns an input stream containing the contents of the specified zip
@ -203,7 +205,7 @@ interface nsIZipReader : nsISupports
* @param aJarSpec the Spec of the URI for the JAR (only used for directory streams)
* @param zipEntry the name of the entry to open the stream from
*/
nsIInputStream getInputStreamWithSpec(in AUTF8String aJarSpec, in string zipEntry);
nsIInputStream getInputStreamWithSpec(in AUTF8String aJarSpec, in AUTF8String zipEntry);
/**
* Returns an object describing the entity which signed
@ -213,7 +215,7 @@ interface nsIZipReader : nsISupports
* stored in the jar, verifyExternalFile (not yet implemented) must
* be called before getPrincipal.
*/
nsIPrincipal getCertificatePrincipal(in string aEntryName);
nsIPrincipal getCertificatePrincipal(in AUTF8String aEntryName);
readonly attribute PRUint32 manifestEntriesCount;
};
@ -221,7 +223,7 @@ interface nsIZipReader : nsISupports
////////////////////////////////////////////////////////////////////////////////
// nsIZipReaderCache
[scriptable, uuid(52c45d86-0cc3-11d4-986e-00c04fa0cf4a)]
[scriptable, uuid(72fc56e5-3e6e-4d11-8967-26ab96071032)]
interface nsIZipReaderCache : nsISupports
{
/**
@ -251,7 +253,7 @@ interface nsIZipReaderCache : nsISupports
*
* See getZip
*/
nsIZipReader getInnerZip(in nsIFile zipFile, in string zipEntry);
nsIZipReader getInnerZip(in nsIFile zipFile, in AUTF8String zipEntry);
};
////////////////////////////////////////////////////////////////////////////////
@ -259,19 +261,15 @@ interface nsIZipReaderCache : nsISupports
%{C++
#define NS_ZIPREADER_CID \
{ /* 7526a738-9632-11d3-8cd9-0060b0fc14a3 */ \
0x7526a738, \
0x9632, \
0x11d3, \
{0x8c, 0xd9, 0x00, 0x60, 0xb0, 0xfc, 0x14, 0xa3} \
{ /* 88e2fd0b-f7f4-480c-9483-7846b00e8dad */ \
0x88e2fd0b, 0xf7f4, 0x480c, \
{ 0x94, 0x83, 0x78, 0x46, 0xb0, 0x0e, 0x8d, 0xad } \
}
#define NS_ZIPREADERCACHE_CID \
{ /* 1b117e16-0cad-11d4-986e-00c04fa0cf4a */ \
0x1b117e16, \
0x0cad, \
0x11d4, \
{0x98, 0x6e, 0x00, 0xc0, 0x4f, 0xa0, 0xcf, 0x4a} \
{ /* 608b7f6f-4b60-40d6-87ed-d933bf53d8c1 */ \
0x608b7f6f, 0x4b60, 0x40d6, \
{ 0x87, 0xed, 0xd9, 0x33, 0xbf, 0x53, 0xd8, 0xc1 } \
}
%}

Просмотреть файл

@ -188,14 +188,13 @@ nsJAR::Open(nsIFile* zipFile)
}
NS_IMETHODIMP
nsJAR::OpenInner(nsIZipReader *aZipReader, const char *aZipEntry)
nsJAR::OpenInner(nsIZipReader *aZipReader, const nsACString &aZipEntry)
{
NS_ENSURE_ARG_POINTER(aZipReader);
NS_ENSURE_ARG_POINTER(aZipEntry);
if (mOpened) return NS_ERROR_FAILURE; // Already open!
PRBool exist;
nsresult rv = aZipReader->HasEntry(nsDependentCString(aZipEntry), &exist);
nsresult rv = aZipReader->HasEntry(aZipEntry, &exist);
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_TRUE(exist, NS_ERROR_FILE_NOT_FOUND);
@ -207,7 +206,7 @@ nsJAR::OpenInner(nsIZipReader *aZipReader, const char *aZipEntry)
mOuterZipEntry.Assign(aZipEntry);
nsRefPtr<nsZipHandle> handle;
rv = nsZipHandle::Init(static_cast<nsJAR*>(aZipReader)->mZip.get(), aZipEntry,
rv = nsZipHandle::Init(static_cast<nsJAR*>(aZipReader)->mZip.get(), PromiseFlatCString(aZipEntry).get(),
getter_AddRefs(handle));
if (NS_FAILED(rv))
return rv;
@ -242,13 +241,13 @@ nsJAR::Close()
}
NS_IMETHODIMP
nsJAR::Test(const char *aEntryName)
nsJAR::Test(const nsACString &aEntryName)
{
return mZip->Test(aEntryName);
return mZip->Test(aEntryName.IsEmpty()? nsnull : PromiseFlatCString(aEntryName).get());
}
NS_IMETHODIMP
nsJAR::Extract(const char *zipEntry, nsIFile* outFile)
nsJAR::Extract(const nsACString &aEntryName, nsIFile* outFile)
{
// nsZipArchive and zlib are not thread safe
// we need to use a lock to prevent bug #51267
@ -258,7 +257,7 @@ nsJAR::Extract(const char *zipEntry, nsIFile* outFile)
nsCOMPtr<nsILocalFile> localFile = do_QueryInterface(outFile, &rv);
if (NS_FAILED(rv)) return rv;
nsZipItem *item = mZip->GetItem(zipEntry);
nsZipItem *item = mZip->GetItem(PromiseFlatCString(aEntryName).get());
NS_ENSURE_TRUE(item, NS_ERROR_FILE_TARGET_DOES_NOT_EXIST);
// Remove existing file or directory so we set permissions correctly.
@ -305,9 +304,9 @@ nsJAR::Extract(const char *zipEntry, nsIFile* outFile)
}
NS_IMETHODIMP
nsJAR::GetEntry(const char *aEntryName, nsIZipEntry* *result)
nsJAR::GetEntry(const nsACString &aEntryName, nsIZipEntry* *result)
{
nsZipItem* zipItem = mZip->GetItem(aEntryName);
nsZipItem* zipItem = mZip->GetItem(PromiseFlatCString(aEntryName).get());
NS_ENSURE_TRUE(zipItem, NS_ERROR_FILE_TARGET_DOES_NOT_EXIST);
nsJARItem* jarItem = new nsJARItem(zipItem);
@ -325,12 +324,12 @@ nsJAR::HasEntry(const nsACString &aEntryName, PRBool *result)
}
NS_IMETHODIMP
nsJAR::FindEntries(const char *aPattern, nsIUTF8StringEnumerator **result)
nsJAR::FindEntries(const nsACString &aPattern, nsIUTF8StringEnumerator **result)
{
NS_ENSURE_ARG_POINTER(result);
nsZipFind *find;
nsresult rv = mZip->FindInit(aPattern, &find);
nsresult rv = mZip->FindInit(aPattern.IsEmpty()? nsnull : PromiseFlatCString(aPattern).get(), &find);
NS_ENSURE_SUCCESS(rv, rv);
nsIUTF8StringEnumerator *zipEnum = new nsJAREnumerator(find);
@ -344,23 +343,23 @@ nsJAR::FindEntries(const char *aPattern, nsIUTF8StringEnumerator **result)
}
NS_IMETHODIMP
nsJAR::GetInputStream(const char* aFilename, nsIInputStream** result)
nsJAR::GetInputStream(const nsACString &aFilename, nsIInputStream** result)
{
return GetInputStreamWithSpec(EmptyCString(), aFilename, result);
}
NS_IMETHODIMP
nsJAR::GetInputStreamWithSpec(const nsACString& aJarDirSpec,
const char* aEntryName, nsIInputStream** result)
const nsACString &aEntryName, nsIInputStream** result)
{
NS_ENSURE_ARG_POINTER(aEntryName);
NS_ENSURE_ARG_POINTER(result);
// Watch out for the jar:foo.zip!/ (aDir is empty) top-level special case!
nsZipItem *item = nsnull;
if (*aEntryName) {
const char *entry = PromiseFlatCString(aEntryName).get();
if (*entry) {
// First check if item exists in jar
item = mZip->GetItem(aEntryName);
item = mZip->GetItem(entry);
if (!item) return NS_ERROR_FILE_TARGET_DOES_NOT_EXIST;
}
nsJARInputStream* jis = new nsJARInputStream();
@ -370,7 +369,7 @@ nsJAR::GetInputStreamWithSpec(const nsACString& aJarDirSpec,
nsresult rv = NS_OK;
if (!item || item->IsDirectory()) {
rv = jis->InitDirectory(this, aJarDirSpec, aEntryName);
rv = jis->InitDirectory(this, aJarDirSpec, entry);
} else {
rv = jis->InitFile(this, item);
}
@ -381,7 +380,7 @@ nsJAR::GetInputStreamWithSpec(const nsACString& aJarDirSpec,
}
NS_IMETHODIMP
nsJAR::GetCertificatePrincipal(const char* aFilename, nsIPrincipal** aPrincipal)
nsJAR::GetCertificatePrincipal(const nsACString &aFilename, nsIPrincipal** aPrincipal)
{
//-- Parameter check
if (!aPrincipal)
@ -401,10 +400,11 @@ nsJAR::GetCertificatePrincipal(const char* aFilename, nsIPrincipal** aPrincipal)
return NS_OK;
PRInt16 requestedStatus;
if (aFilename)
const char *filename = PromiseFlatCString(aFilename).get();
if (*filename)
{
//-- Find the item
nsCStringKey key(aFilename);
nsCStringKey key(filename);
nsJARManifestItem* manItem = static_cast<nsJARManifestItem*>(mManifestData.Get(&key));
if (!manItem)
return NS_OK;
@ -424,7 +424,7 @@ nsJAR::GetCertificatePrincipal(const char* aFilename, nsIPrincipal** aPrincipal)
requestedStatus = mGlobalStatus;
if (requestedStatus != JAR_VALID_MANIFEST)
ReportError(aFilename, requestedStatus);
ReportError(filename, requestedStatus);
else // Valid signature
{
*aPrincipal = mPrincipal;
@ -452,7 +452,7 @@ nsJAR::GetJarPath(nsACString& aResult)
// nsJAR private implementation
//----------------------------------------------
nsresult
nsJAR::LoadEntry(const char* aFilename, char** aBuf, PRUint32* aBufLen)
nsJAR::LoadEntry(const nsACString &aFilename, char** aBuf, PRUint32* aBufLen)
{
//-- Get a stream for reading the file
nsresult rv;
@ -529,7 +529,7 @@ nsJAR::ParseManifest()
return NS_OK;
//-- (1)Manifest (MF) file
nsCOMPtr<nsIUTF8StringEnumerator> files;
nsresult rv = FindEntries(JAR_MF_SEARCH_STRING, getter_AddRefs(files));
nsresult rv = FindEntries(nsDependentCString(JAR_MF_SEARCH_STRING), getter_AddRefs(files));
if (!files) rv = NS_ERROR_FAILURE;
if (NS_FAILED(rv)) return rv;
@ -559,7 +559,7 @@ nsJAR::ParseManifest()
nsXPIDLCString manifestBuffer;
PRUint32 manifestLen;
rv = LoadEntry(manifestFilename.get(), getter_Copies(manifestBuffer), &manifestLen);
rv = LoadEntry(manifestFilename, getter_Copies(manifestBuffer), &manifestLen);
if (NS_FAILED(rv)) return rv;
//-- Parse it
@ -568,7 +568,7 @@ nsJAR::ParseManifest()
//-- (2)Signature (SF) file
// If there are multiple signatures, we select one.
rv = FindEntries(JAR_SF_SEARCH_STRING, getter_AddRefs(files));
rv = FindEntries(nsDependentCString(JAR_SF_SEARCH_STRING), getter_AddRefs(files));
if (!files) rv = NS_ERROR_FAILURE;
if (NS_FAILED(rv)) return rv;
//-- Get an SF file
@ -583,7 +583,7 @@ nsJAR::ParseManifest()
rv = files->GetNext(manifestFilename);
if (NS_FAILED(rv)) return rv;
rv = LoadEntry(manifestFilename.get(), getter_Copies(manifestBuffer), &manifestLen);
rv = LoadEntry(manifestFilename, getter_Copies(manifestBuffer), &manifestLen);
if (NS_FAILED(rv)) return rv;
//-- Get its corresponding signature file
@ -595,12 +595,12 @@ nsJAR::ParseManifest()
PRUint32 sigLen;
{
nsCAutoString tempFilename(sigFilename); tempFilename.Append("rsa", 3);
rv = LoadEntry(tempFilename.get(), getter_Copies(sigBuffer), &sigLen);
rv = LoadEntry(tempFilename, getter_Copies(sigBuffer), &sigLen);
}
if (NS_FAILED(rv))
{
nsCAutoString tempFilename(sigFilename); tempFilename.Append("RSA", 3);
rv = LoadEntry(tempFilename.get(), getter_Copies(sigBuffer), &sigLen);
rv = LoadEntry(tempFilename, getter_Copies(sigBuffer), &sigLen);
}
if (NS_FAILED(rv))
{
@ -1152,7 +1152,7 @@ nsZipReaderCache::GetZip(nsIFile* zipFile, nsIZipReader* *result)
}
NS_IMETHODIMP
nsZipReaderCache::GetInnerZip(nsIFile* zipFile, const char *entry,
nsZipReaderCache::GetInnerZip(nsIFile* zipFile, const nsACString &entry,
nsIZipReader* *result)
{
NS_ENSURE_ARG_POINTER(zipFile);

Просмотреть файл

@ -147,7 +147,7 @@ class nsJAR : public nsIZipReader
nsresult ParseManifest();
void ReportError(const char* aFilename, PRInt16 errorCode);
nsresult LoadEntry(const char* aFilename, char** aBuf,
nsresult LoadEntry(const nsACString &aFilename, char** aBuf,
PRUint32* aBufLen = nsnull);
PRInt32 ReadLine(const char** src);
nsresult ParseOneFile(const char* filebuf, PRInt16 aFileType);

Просмотреть файл

@ -149,11 +149,11 @@ nsJARInputThunk::EnsureJarStream()
NS_ENSURE_STATE(!mJarDirSpec.IsEmpty());
rv = mJarReader->GetInputStreamWithSpec(mJarDirSpec,
mJarEntry.get(),
mJarEntry,
getter_AddRefs(mJarStream));
}
else {
rv = mJarReader->GetInputStream(mJarEntry.get(),
rv = mJarReader->GetInputStream(mJarEntry,
getter_AddRefs(mJarStream));
}
if (NS_FAILED(rv)) {
@ -303,7 +303,7 @@ nsJARChannel::CreateJarInput(nsIZipReaderCache *jarCache)
if (mInnerJarEntry.IsEmpty())
rv = jarCache->GetZip(mJarFile, getter_AddRefs(reader));
else
rv = jarCache->GetInnerZip(mJarFile, mInnerJarEntry.get(),
rv = jarCache->GetInnerZip(mJarFile, mInnerJarEntry,
getter_AddRefs(reader));
} else {
// create an uncached jar reader
@ -322,7 +322,7 @@ nsJARChannel::CreateJarInput(nsIZipReaderCache *jarCache)
if (NS_FAILED(rv))
return rv;
rv = reader->OpenInner(outerReader, mInnerJarEntry.get());
rv = reader->OpenInner(outerReader, mInnerJarEntry);
}
}
if (NS_FAILED(rv))
@ -535,7 +535,7 @@ nsJARChannel::GetOwner(nsISupports **result)
return NS_ERROR_NOT_INITIALIZED;
nsCOMPtr<nsIPrincipal> cert;
rv = jarReader->GetCertificatePrincipal(mJarEntry.get(), getter_AddRefs(cert));
rv = jarReader->GetCertificatePrincipal(mJarEntry, getter_AddRefs(cert));
if (NS_FAILED(rv)) return rv;
if (cert) {

Двоичные данные
modules/libjar/test/unit/data/test_umlaute.zip Normal file

Двоичный файл не отображается.

Просмотреть файл

@ -0,0 +1,40 @@
const Cc = Components.classes;
const Ci = Components.interfaces;
function run_test() {
var dirService = Cc["@mozilla.org/file/directory_service;1"].getService(Ci.nsIProperties);
var tmpDir = dirService.get("TmpD", Ci.nsIFile);
var zipfile = do_get_file("data/test_umlaute.zip");
var testFile = tmpDir.clone();
testFile.append("test_\u00FC.txt");
if (testFile.exists()) {
testFile.remove(false);
}
var zipreader = Cc["@mozilla.org/libjar/zip-reader;1"].createInstance(Ci.nsIZipReader);
zipreader.open(zipfile);
var entries = zipreader.findEntries(null);
do_check_true(entries.hasMore());
var entryName = entries.getNext();
do_check_eq(entryName, "test_\u00FC.txt");
do_check_true(zipreader.hasEntry(entryName));
var target = tmpDir.clone();
target.append(entryName);
target.create(Ci.nsILocalFile.NORMAL_FILE_TYPE, 0640);
zipreader.extract(entryName, target);
var entry = zipreader.getEntry(entryName);
do_check_true(entry != null);
zipreader.test(entryName);
zipreader.close();
}

Просмотреть файл

@ -20,3 +20,5 @@ tail =
[test_jarinput_stream_zipreader_reference.js]
[test_not_found.js]
[test_uncompressed.js]
[test_umlaute.js]

Просмотреть файл

@ -472,7 +472,7 @@ Preferences::ReadExtensionPrefs(nsILocalFile *aFile)
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIUTF8StringEnumerator> files;
rv = reader->FindEntries("defaults/preferences/*.(J|j)(S|s)$",
rv = reader->FindEntries(nsDependentCString("defaults/preferences/*.(J|j)(S|s)$"),
getter_AddRefs(files));
NS_ENSURE_SUCCESS(rv, rv);
@ -485,7 +485,7 @@ Preferences::ReadExtensionPrefs(nsILocalFile *aFile)
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIInputStream> stream;
rv = reader->GetInputStream(entry.get(), getter_AddRefs(stream));
rv = reader->GetInputStream(entry, getter_AddRefs(stream));
NS_ENSURE_SUCCESS(rv, rv);
PRUint32 avail, read;

Просмотреть файл

@ -537,7 +537,7 @@ LoadEntry(nsIZipReader* aReader, const char* aName)
return NULL;
nsCOMPtr<nsIInputStream> is;
nsresult rv = aReader->GetInputStream(aName, getter_AddRefs(is));
nsresult rv = aReader->GetInputStream(nsDependentCString(aName), getter_AddRefs(is));
if (NS_FAILED(rv))
return NULL;

Просмотреть файл

@ -638,7 +638,7 @@ VerifySigning(nsIZipReader* hZip, nsIPrincipal* aPrincipal)
// See if the archive is signed at all first
nsCOMPtr<nsIPrincipal> principal;
nsresult rv = hZip->GetCertificatePrincipal(nsnull, getter_AddRefs(principal));
nsresult rv = hZip->GetCertificatePrincipal(EmptyCString(), getter_AddRefs(principal));
if (NS_FAILED(rv) || !principal)
return NS_ERROR_FAILURE;
@ -646,7 +646,7 @@ VerifySigning(nsIZipReader* hZip, nsIPrincipal* aPrincipal)
// first verify all files in the jar are also in the manifest.
nsCOMPtr<nsIUTF8StringEnumerator> entries;
rv = hZip->FindEntries(nsnull, getter_AddRefs(entries));
rv = hZip->FindEntries(EmptyCString(), getter_AddRefs(entries));
if (NS_FAILED(rv))
return rv;
@ -667,7 +667,7 @@ VerifySigning(nsIZipReader* hZip, nsIPrincipal* aPrincipal)
entryCount++;
// Each entry must be signed
rv = hZip->GetCertificatePrincipal(name.get(), getter_AddRefs(principal));
rv = hZip->GetCertificatePrincipal(name, getter_AddRefs(principal));
if (NS_FAILED(rv) || !principal) return NS_ERROR_FAILURE;
PRBool equal;
@ -713,7 +713,7 @@ OpenAndValidateArchive(nsIZipReader* hZip, nsIFile* jarFile, nsIPrincipal* aPrin
return nsInstall::CANT_READ_ARCHIVE;
// CRC check the integrity of all items in this archive
rv = hZip->Test(nsnull);
rv = hZip->Test(EmptyCString());
if (NS_FAILED(rv))
{
NS_WARNING("CRC check of archive failed!");
@ -727,7 +727,7 @@ OpenAndValidateArchive(nsIZipReader* hZip, nsIFile* jarFile, nsIPrincipal* aPrin
return nsInstall::INVALID_SIGNATURE;
}
if (NS_FAILED(hZip->Test("install.rdf")))
if (NS_FAILED(hZip->Test(nsDependentCString("install.rdf"))))
{
NS_WARNING("Archive did not contain an install manifest!");
return nsInstall::NO_INSTALL_SCRIPT;