Bug 710693 - Move internal encoding check into nsCharsetAlias. r=smontagu

This commit is contained in:
Masatoshi Kimura 2012-05-24 18:45:10 -04:00
parent 2780df842f
commit 9cee24d959
10 changed files with 133 additions and 99 deletions

View File

@ -1753,7 +1753,7 @@ gfxFontUtils::DecodeFontName(const PRUint8 *aNameData, PRInt32 aByteLen,
}
nsCOMPtr<nsIUnicodeDecoder> decoder;
rv = ccm->GetUnicodeDecoderRawInternal(csName, getter_AddRefs(decoder));
rv = ccm->GetUnicodeDecoderRaw(csName, getter_AddRefs(decoder));
if (NS_FAILED(rv)) {
NS_WARNING("failed to get the decoder for a font name string");
return false;

View File

@ -39,6 +39,7 @@ LOCAL_INCLUDES = \
-I$(srcdir)/../strres/src \
-I$(srcdir)/../locale/src \
-I$(srcdir)/../locale/src/$(LOCALE_DIR) \
-I$(srcdir)/../uconv/src \
$(NULL)
SHARED_LIBRARY_LIBS = \

View File

@ -28,6 +28,9 @@
// locale
#include "nsLocaleConstructors.h"
// uconv
#include "nsCharsetConverterManager.h"
NS_GENERIC_FACTORY_CONSTRUCTOR(nsJISx4051LineBreaker)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsSampleWordBreaker)
@ -148,10 +151,20 @@ static const mozilla::Module::ContractIDEntry kIntlContracts[] = {
{ NULL }
};
static void
I18nModuleDtor()
{
nsCharsetConverterManager::Shutdown();
}
static const mozilla::Module kIntlModule = {
mozilla::Module::kVersion,
kIntlCIDs,
kIntlContracts,
NULL,
NULL,
NULL,
I18nModuleDtor
};
NSMODULE_DEFN(nsI18nModule) = &kIntlModule;

View File

@ -9,8 +9,12 @@
#include "nscore.h"
#include "nsStringGlue.h"
class nsCharsetConverterManager;
class nsCharsetAlias
{
friend class nsCharsetConverterManager;
static nsresult GetPreferredInternal(const nsACString& aAlias, nsACString& aResult);
public:
static nsresult GetPreferred(const nsACString& aAlias, nsACString& aResult);
static nsresult Equals(const nsACString& aCharset1, const nsACString& aCharset2, bool* aResult);

View File

@ -55,6 +55,10 @@ EXTRA_JS_MODULES = \
# we don't want the shared lib, but we want to force the creation of a static lib.
FORCE_STATIC_LIB = 1
LOCAL_INCLUDES = \
-I$(topsrcdir)/intl/uconv/src \
$(NULL)
include $(topsrcdir)/config/rules.mk
nsCharsetAlias.$(OBJ_SUFFIX): charsetalias.properties.h

View File

@ -8,6 +8,10 @@
#include "nsCharsetAlias.h"
#include "pratom.h"
// for NS_ERROR_UCONV_NOCONV
#include "nsEncoderDecoderUtils.h"
#include "nsCharsetConverterManager.h"
// for NS_IMPL_IDS only
#include "nsIPlatformCharset.h"
@ -25,11 +29,9 @@ static const char* kAliases[][3] = {
//--------------------------------------------------------------
// static
nsresult
nsCharsetAlias::GetPreferred(const nsACString& aAlias,
nsACString& oResult)
nsCharsetAlias::GetPreferredInternal(const nsACString& aAlias,
nsACString& oResult)
{
if (aAlias.IsEmpty()) return NS_ERROR_NULL_POINTER;
nsCAutoString key(aAlias);
ToLowerCase(key);
@ -37,6 +39,24 @@ nsCharsetAlias::GetPreferred(const nsACString& aAlias,
ArrayLength(kAliases), key, oResult);
}
//--------------------------------------------------------------
// static
nsresult
nsCharsetAlias::GetPreferred(const nsACString& aAlias,
nsACString& oResult)
{
if (aAlias.IsEmpty()) return NS_ERROR_NULL_POINTER;
nsresult res = GetPreferredInternal(aAlias, oResult);
if (NS_FAILED(res))
return res;
if (nsCharsetConverterManager::IsInternal(oResult))
return NS_ERROR_UCONV_NOCONV;
return res;
}
//--------------------------------------------------------------
// static
nsresult
@ -57,12 +77,12 @@ nsCharsetAlias::Equals(const nsACString& aCharset1,
*oResult = false;
nsCAutoString name1;
res = GetPreferred(aCharset1, name1);
res = GetPreferredInternal(aCharset1, name1);
if (NS_FAILED(res))
return res;
nsCAutoString name2;
res = GetPreferred(aCharset2, name2);
res = GetPreferredInternal(aCharset2, name2);
if (NS_FAILED(res))
return res;

View File

@ -33,20 +33,16 @@ interface nsIUTF8StringEnumerator;
* @created 21/Feb/2000
* @author Catalin Rotaru [CATA]
*/
[scriptable, uuid(bf733b00-198f-4553-a061-637a21793330)]
[scriptable, uuid(a0550d46-8d9c-47dd-acc7-c083620dff12)]
interface nsICharsetConverterManager : nsISupports
{
/**
* Get the Unicode decoder for the given charset.
* The "Raw" version skips charset alias resolution
* The "Internal" version will return a decoder for any charset; the others
* will return NS_ERROR_UCONV_NOCONV if the requested charsets is
* vulnerable to XSS attacks and should not be used with untrusted input
*/
[noscript] nsIUnicodeDecoder getUnicodeDecoder(in string charset);
[noscript] nsIUnicodeDecoder getUnicodeDecoderRaw(in string charset);
[noscript] nsIUnicodeDecoder getUnicodeDecoderInternal(in string charset);
[noscript] nsIUnicodeDecoder getUnicodeDecoderRawInternal(in string charset);
/**
* Get the Unicode encoder for the given charset.

View File

@ -27,26 +27,32 @@
// just for CONTRACTIDs
#include "nsCharsetConverterManager.h"
static nsIStringBundle * sDataBundle;
static nsIStringBundle * sTitleBundle;
// Class nsCharsetConverterManager [implementation]
NS_IMPL_THREADSAFE_ISUPPORTS1(nsCharsetConverterManager,
nsICharsetConverterManager)
nsCharsetConverterManager::nsCharsetConverterManager()
: mDataBundle(NULL)
, mTitleBundle(NULL)
{
}
nsCharsetConverterManager::~nsCharsetConverterManager()
{
NS_IF_RELEASE(mDataBundle);
NS_IF_RELEASE(mTitleBundle);
}
nsresult nsCharsetConverterManager::LoadExtensibleBundle(
const char* aCategory,
nsIStringBundle ** aResult)
//static
void nsCharsetConverterManager::Shutdown()
{
NS_IF_RELEASE(sDataBundle);
NS_IF_RELEASE(sTitleBundle);
}
static
nsresult LoadExtensibleBundle(const char* aCategory,
nsIStringBundle ** aResult)
{
nsCOMPtr<nsIStringBundleService> sbServ =
mozilla::services::GetStringBundleService();
@ -56,10 +62,11 @@ nsresult nsCharsetConverterManager::LoadExtensibleBundle(
return sbServ->CreateExtensibleBundle(aCategory, aResult);
}
nsresult nsCharsetConverterManager::GetBundleValue(nsIStringBundle * aBundle,
const char * aName,
const nsAFlatString& aProp,
PRUnichar ** aResult)
static
nsresult GetBundleValue(nsIStringBundle * aBundle,
const char * aName,
const nsAFlatString& aProp,
PRUnichar ** aResult)
{
nsAutoString key;
@ -70,10 +77,11 @@ nsresult nsCharsetConverterManager::GetBundleValue(nsIStringBundle * aBundle,
return aBundle->GetStringFromName(key.get(), aResult);
}
nsresult nsCharsetConverterManager::GetBundleValue(nsIStringBundle * aBundle,
const char * aName,
const nsAFlatString& aProp,
nsAString& aResult)
static
nsresult GetBundleValue(nsIStringBundle * aBundle,
const char * aName,
const nsAFlatString& aProp,
nsAString& aResult)
{
nsresult rv = NS_OK;
@ -87,6 +95,35 @@ nsresult nsCharsetConverterManager::GetBundleValue(nsIStringBundle * aBundle,
return NS_OK;
}
static
nsresult GetCharsetDataImpl(const char * aCharset, const PRUnichar * aProp,
nsAString& aResult)
{
if (aCharset == NULL)
return NS_ERROR_NULL_POINTER;
// aProp can be NULL
if (sDataBundle == NULL) {
nsresult rv = LoadExtensibleBundle(NS_DATA_BUNDLE_CATEGORY, &sDataBundle);
if (NS_FAILED(rv))
return rv;
}
return GetBundleValue(sDataBundle, aCharset, nsDependentString(aProp), aResult);
}
//static
bool nsCharsetConverterManager::IsInternal(const nsACString& aCharset)
{
nsAutoString str;
// fully qualify to possibly avoid vtable call
nsresult rv = GetCharsetDataImpl(PromiseFlatCString(aCharset).get(),
NS_LITERAL_STRING(".isXSSVulnerable").get(),
str);
return NS_SUCCEEDED(rv);
}
//----------------------------------------------------------------------------//----------------------------------------------------------------------------
// Interface nsICharsetConverterManager [implementation]
@ -132,29 +169,17 @@ nsCharsetConverterManager::GetUnicodeEncoderRaw(const char * aDest,
return rv;
}
NS_IMETHODIMP
nsCharsetConverterManager::GetUnicodeDecoderRaw(const char * aSrc,
nsIUnicodeDecoder ** aResult)
{
nsresult rv;
nsAutoString str;
rv = GetCharsetData(aSrc, NS_LITERAL_STRING(".isXSSVulnerable").get(), str);
if (NS_SUCCEEDED(rv))
return NS_ERROR_UCONV_NOCONV;
return GetUnicodeDecoderRawInternal(aSrc, aResult);
}
NS_IMETHODIMP
nsCharsetConverterManager::GetUnicodeDecoder(const char * aSrc,
nsIUnicodeDecoder ** aResult)
{
// resolve the charset first
nsCAutoString charset;
// fully qualify to possibly avoid vtable call
nsCharsetConverterManager::GetCharsetAlias(aSrc, charset);
nsresult rv = nsCharsetConverterManager::GetCharsetAlias(aSrc, charset);
if (NS_FAILED(rv))
return rv;
return nsCharsetConverterManager::GetUnicodeDecoderRaw(charset.get(),
aResult);
@ -166,18 +191,18 @@ nsCharsetConverterManager::GetUnicodeDecoderInternal(const char * aSrc,
{
// resolve the charset first
nsCAutoString charset;
// fully qualify to possibly avoid vtable call
nsresult rv = nsCharsetConverterManager::GetCharsetAlias(aSrc, charset);
nsresult rv = nsCharsetAlias::GetPreferredInternal(nsDependentCString(aSrc),
charset);
NS_ENSURE_SUCCESS(rv, rv);
return nsCharsetConverterManager::GetUnicodeDecoderRawInternal(charset.get(),
aResult);
return nsCharsetConverterManager::GetUnicodeDecoderRaw(charset.get(),
aResult);
}
NS_IMETHODIMP
nsCharsetConverterManager::GetUnicodeDecoderRawInternal(const char * aSrc,
nsIUnicodeDecoder ** aResult)
nsCharsetConverterManager::GetUnicodeDecoderRaw(const char * aSrc,
nsIUnicodeDecoder ** aResult)
{
*aResult= nsnull;
nsCOMPtr<nsIUnicodeDecoder> decoder;
@ -186,7 +211,7 @@ nsCharsetConverterManager::GetUnicodeDecoderRawInternal(const char * aSrc,
NS_NAMED_LITERAL_CSTRING(contractbase, NS_UNICODEDECODER_CONTRACTID_BASE);
nsDependentCString src(aSrc);
decoder = do_CreateInstance(PromiseFlatCString(contractbase + src).get(),
&rv);
NS_ENSURE_SUCCESS(rv, NS_ERROR_UCONV_NOCONV);
@ -195,10 +220,10 @@ nsCharsetConverterManager::GetUnicodeDecoderRawInternal(const char * aSrc,
return rv;
}
nsresult
nsCharsetConverterManager::GetList(const nsACString& aCategory,
const nsACString& aPrefix,
nsIUTF8StringEnumerator** aResult)
static
nsresult GetList(const nsACString& aCategory,
const nsACString& aPrefix,
nsIUTF8StringEnumerator** aResult)
{
if (aResult == NULL)
return NS_ERROR_NULL_POINTER;
@ -289,12 +314,12 @@ nsCharsetConverterManager::GetCharsetTitle(const char * aCharset,
{
NS_ENSURE_ARG_POINTER(aCharset);
if (mTitleBundle == NULL) {
nsresult rv = LoadExtensibleBundle(NS_TITLE_BUNDLE_CATEGORY, &mTitleBundle);
if (sTitleBundle == NULL) {
nsresult rv = LoadExtensibleBundle(NS_TITLE_BUNDLE_CATEGORY, &sTitleBundle);
NS_ENSURE_SUCCESS(rv, rv);
}
return GetBundleValue(mTitleBundle, aCharset, NS_LITERAL_STRING(".title"), aResult);
return GetBundleValue(sTitleBundle, aCharset, NS_LITERAL_STRING(".title"), aResult);
}
NS_IMETHODIMP
@ -302,17 +327,7 @@ nsCharsetConverterManager::GetCharsetData(const char * aCharset,
const PRUnichar * aProp,
nsAString& aResult)
{
if (aCharset == NULL)
return NS_ERROR_NULL_POINTER;
// aProp can be NULL
if (mDataBundle == NULL) {
nsresult rv = LoadExtensibleBundle(NS_DATA_BUNDLE_CATEGORY, &mDataBundle);
if (NS_FAILED(rv))
return rv;
}
return GetBundleValue(mDataBundle, aCharset, nsDependentString(aProp), aResult);
return GetCharsetDataImpl(aCharset, aProp, aResult);
}
NS_IMETHODIMP
@ -336,19 +351,10 @@ nsCharsetConverterManager::GetCharsetLangGroupRaw(const char * aCharset,
{
*aResult = nsnull;
if (aCharset == NULL)
return NS_ERROR_NULL_POINTER;
nsresult rv = NS_OK;
if (mDataBundle == NULL) {
rv = LoadExtensibleBundle(NS_DATA_BUNDLE_CATEGORY, &mDataBundle);
if (NS_FAILED(rv))
return rv;
}
nsAutoString langGroup;
rv = GetBundleValue(mDataBundle, aCharset, NS_LITERAL_STRING(".LangGroup"), langGroup);
// fully qualify to possibly avoid vtable call
nsresult rv = nsCharsetConverterManager::GetCharsetData(
aCharset, NS_LITERAL_STRING(".LangGroup").get(), langGroup);
if (NS_SUCCEEDED(rv)) {
ToLowerCase(langGroup); // use lowercase for all language atoms

View File

@ -11,34 +11,24 @@
#include "nsInterfaceHashtable.h"
#include "mozilla/Mutex.h"
class nsCharsetAlias;
class nsCharsetConverterManager : public nsICharsetConverterManager
{
friend class nsCharsetAlias;
NS_DECL_ISUPPORTS
NS_DECL_NSICHARSETCONVERTERMANAGER
public:
nsCharsetConverterManager();
virtual ~nsCharsetConverterManager();
static void Shutdown();
private:
nsIStringBundle * mDataBundle;
nsIStringBundle * mTitleBundle;
nsresult LoadExtensibleBundle(const char * aRegistryKey,
nsIStringBundle ** aResult);
nsresult GetBundleValue(nsIStringBundle * aBundle,
const char * aName,
const nsAFlatString& aProp, PRUnichar ** aResult);
nsresult GetBundleValue(nsIStringBundle * aBundle,
const char * aName,
const nsAFlatString& aProp, nsAString& aResult);
nsresult GetList(const nsACString& aCategory,
const nsACString& aPrefix,
nsIUTF8StringEnumerator** aResult);
static bool IsInternal(const nsACString& aCharset);
};
#endif // nsCharsetConverterManager_h__

View File

@ -9,7 +9,7 @@ function run_test()
while (decoderList.hasMore()) {
var decoder = decoderList.getNext();
try {
var langGroup = ccManager.getCharsetLangGroup(decoder);
var langGroup = ccManager.getCharsetLangGroupRaw(decoder);
} catch(e) {
dump("no langGroup for " + decoder + "\n");
failures = true;