intl/unicharutil/src/nsEntityConverter.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 #include "nsEntityConverter.h"
     7 #include "nsLiteralString.h"
     8 #include "nsString.h"
     9 #include "mozilla/Services.h"
    10 #include "nsServiceManagerUtils.h"
    11 #include "nsCRT.h"
    13 //
    14 // implementation methods
    15 //
    16 nsEntityConverter::nsEntityConverter() :
    17     mVersionList(nullptr),
    18     mVersionListLength(0)
    19 {
    20 }
    22 nsEntityConverter::~nsEntityConverter()
    23 {
    24     if (mVersionList)
    25         delete [] mVersionList;
    26 }
    28 NS_IMETHODIMP 
    29 nsEntityConverter::LoadVersionPropertyFile()
    30 {
    31     NS_NAMED_LITERAL_CSTRING(url, "resource://gre/res/entityTables/htmlEntityVersions.properties");
    33     nsCOMPtr<nsIStringBundleService> bundleService =
    34         mozilla::services::GetStringBundleService();
    35     if (!bundleService)
    36         return NS_ERROR_FAILURE;
    38     nsCOMPtr<nsIStringBundle> entities;
    39     nsresult rv = bundleService->CreateBundle(url.get(), getter_AddRefs(entities));
    40     if (NS_FAILED(rv)) return rv;
    42     nsresult result;
    44     nsAutoString key;
    45     nsXPIDLString value;
    46     rv = entities->GetStringFromName(MOZ_UTF16("length"),
    47                                      getter_Copies(value));
    48     NS_ASSERTION(NS_SUCCEEDED(rv),"nsEntityConverter: malformed entity table\n");
    49     if (NS_FAILED(rv)) return rv;
    51     mVersionListLength = nsAutoString(value).ToInteger(&result);
    52     NS_ASSERTION(32 >= mVersionListLength,"nsEntityConverter: malformed entity table\n");
    53     if (32 < mVersionListLength) return NS_ERROR_FAILURE;
    55     mVersionList = new nsEntityVersionList[mVersionListLength];
    56     if (!mVersionList) return NS_ERROR_OUT_OF_MEMORY;
    58     for (uint32_t i = 0; i < mVersionListLength && NS_SUCCEEDED(rv); i++) {
    59         key.SetLength(0);
    60         key.AppendInt(i+1, 10);
    61         rv = entities->GetStringFromName(key.get(), getter_Copies(value));
    62         uint32_t len = value.Length();
    63         if (kVERSION_STRING_LEN < len) return NS_ERROR_UNEXPECTED;
    65         memcpy(mVersionList[i].mEntityListName, value.get(), len*sizeof(char16_t));
    66         mVersionList[i].mEntityListName[len] = 0;
    67         mVersionList[i].mVersion = (1 << i);
    68     }
    70     return NS_OK;
    71 }
    73 already_AddRefed<nsIStringBundle>
    74 nsEntityConverter::LoadEntityBundle(uint32_t version)
    75 {
    76   nsAutoCString url(NS_LITERAL_CSTRING("resource://gre/res/entityTables/"));
    77   nsresult rv;
    79   nsCOMPtr<nsIStringBundleService> bundleService =
    80       do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv);
    81   NS_ENSURE_SUCCESS(rv, nullptr);
    83   const char16_t *versionName = GetVersionName(version);
    84   NS_ENSURE_TRUE(versionName, nullptr);
    86   // all property file names are ASCII, like "html40Latin1" so this is safe
    87   LossyAppendUTF16toASCII(versionName, url);
    88   url.Append(".properties");
    90   nsCOMPtr<nsIStringBundle> bundle;
    91   rv = bundleService->CreateBundle(url.get(), getter_AddRefs(bundle));
    92   NS_ENSURE_SUCCESS(rv, nullptr);
    94   return bundle.forget();
    95 }
    97 const char16_t*
    98 nsEntityConverter:: GetVersionName(uint32_t versionNumber)
    99 {
   100   for (uint32_t i = 0; i < mVersionListLength; i++) {
   101     if (versionNumber == mVersionList[i].mVersion)
   102       return mVersionList[i].mEntityListName;
   103   }
   105   return nullptr;
   106 }
   108 nsIStringBundle*
   109 nsEntityConverter:: GetVersionBundleInstance(uint32_t versionNumber)
   110 {
   111   if (!mVersionList) {
   112     // load the property file which contains available version names
   113     // and generate a list of version/name pair
   114     if (NS_FAILED(LoadVersionPropertyFile()))
   115       return nullptr;
   116   }
   118   uint32_t i;
   119   for (i = 0; i < mVersionListLength; i++) {
   120     if (versionNumber == mVersionList[i].mVersion) {
   121       if (!mVersionList[i].mEntities)
   122       { // not loaded
   123         // load the property file
   124         mVersionList[i].mEntities = LoadEntityBundle(versionNumber);
   125         NS_ASSERTION(mVersionList[i].mEntities, "LoadEntityBundle failed");
   126       }
   127       return mVersionList[i].mEntities.get();
   128     }
   129   }
   131   return nullptr;
   132 }
   135 //
   136 // nsISupports methods
   137 //
   138 NS_IMPL_ISUPPORTS(nsEntityConverter,nsIEntityConverter)
   141 //
   142 // nsIEntityConverter
   143 //
   144 NS_IMETHODIMP
   145 nsEntityConverter::ConvertToEntity(char16_t character, uint32_t entityVersion, char **_retval)
   146 { 
   147   return ConvertUTF32ToEntity((uint32_t)character, entityVersion, _retval);
   148 }
   150 NS_IMETHODIMP
   151 nsEntityConverter::ConvertUTF32ToEntity(uint32_t character, uint32_t entityVersion, char **_retval)
   152 {
   153   NS_ASSERTION(_retval, "null ptr- _retval");
   154   if(nullptr == _retval)
   155     return NS_ERROR_NULL_POINTER;
   156   *_retval = nullptr;
   158   for (uint32_t mask = 1, mask2 = 0xFFFFFFFFL; (0!=(entityVersion & mask2)); mask<<=1, mask2<<=1) {
   159     if (0 == (entityVersion & mask)) 
   160       continue;
   161     nsIStringBundle* entities = GetVersionBundleInstance(entityVersion & mask);
   162     NS_ASSERTION(entities, "Cannot get the property file");
   164     if (!entities) 
   165       continue;
   167     nsAutoString key(NS_LITERAL_STRING("entity."));
   168     key.AppendInt(character,10);
   170     nsXPIDLString value;
   171     nsresult rv = entities->GetStringFromName(key.get(), getter_Copies(value));
   172     if (NS_SUCCEEDED(rv)) {
   173       *_retval = ToNewCString(value);
   174       if(nullptr == *_retval)
   175         return NS_ERROR_OUT_OF_MEMORY;
   176       else
   177         return NS_OK;
   178     }
   179   }
   180 	return NS_ERROR_ILLEGAL_VALUE;
   181 }
   183 NS_IMETHODIMP
   184 nsEntityConverter::ConvertToEntities(const char16_t *inString, uint32_t entityVersion, char16_t **_retval)
   185 {
   186   NS_ENSURE_ARG_POINTER(inString);
   187   NS_ENSURE_ARG_POINTER(_retval);
   189   *_retval = nullptr;
   191   nsString outString;
   193   // per character look for the entity
   194   uint32_t len = NS_strlen(inString);
   195   for (uint32_t i = 0; i < len; i++) {
   196     nsAutoString key(NS_LITERAL_STRING("entity."));
   197     if (NS_IS_HIGH_SURROGATE(inString[i]) &&
   198         i + 2 < len &&
   199         NS_IS_LOW_SURROGATE(inString[i + 1])) {
   200       key.AppendInt(SURROGATE_TO_UCS4(inString[i], inString[i+1]), 10);
   201       ++i;
   202     }
   203     else {
   204       key.AppendInt(inString[i],10);
   205     }
   207     nsXPIDLString value;
   208     const char16_t *entity = nullptr;
   210     for (uint32_t mask = 1, mask2 = 0xFFFFFFFFL; (0!=(entityVersion & mask2)); mask<<=1, mask2<<=1) {
   211       if (0 == (entityVersion & mask)) 
   212          continue;
   213       nsIStringBundle* entities = GetVersionBundleInstance(entityVersion & mask);
   214       NS_ASSERTION(entities, "Cannot get the property file");
   216       if (!entities) 
   217           continue;
   219       nsresult rv = entities->GetStringFromName(key.get(),
   220                                                 getter_Copies(value));
   221       if (NS_SUCCEEDED(rv)) {
   222         entity = value.get();
   223         break;
   224       }
   225     }
   226     if (entity) {
   227       outString.Append(entity);
   228     }
   229     else {
   230       outString.Append(&inString[i], 1);
   231     }
   232   }
   234   *_retval = ToNewUnicode(outString);
   235   if (!*_retval) 
   236     return NS_ERROR_OUT_OF_MEMORY;
   238   return NS_OK;
   239 }

mercurial