Sat, 03 Jan 2015 20:18:00 +0100
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.
michael@0 | 1 | /* |
michael@0 | 2 | * Copyright (c) 2007 2008 |
michael@0 | 3 | * Francois Dumont |
michael@0 | 4 | * |
michael@0 | 5 | * This material is provided "as is", with absolutely no warranty expressed |
michael@0 | 6 | * or implied. Any use is at your own risk. |
michael@0 | 7 | * |
michael@0 | 8 | * Permission to use or copy this software for any purpose is hereby granted |
michael@0 | 9 | * without fee, provided the above notices are retained on all copies. |
michael@0 | 10 | * Permission to modify the code and to distribute modified code is granted, |
michael@0 | 11 | * provided the above notices are retained, and a notice that the code was |
michael@0 | 12 | * modified is included with the above copyright notice. |
michael@0 | 13 | * |
michael@0 | 14 | */ |
michael@0 | 15 | |
michael@0 | 16 | #if defined (_STLP_USE_SAFE_STRING_FUNCTIONS) |
michael@0 | 17 | # define _STLP_WCSNCPY(D, DS, S, C) wcsncpy_s(D, DS, S, C) |
michael@0 | 18 | #else |
michael@0 | 19 | # define _STLP_WCSNCPY(D, DS, S, C) wcsncpy(D, S, C) |
michael@0 | 20 | #endif |
michael@0 | 21 | |
michael@0 | 22 | static const wchar_t* __wtrue_name = L"true"; |
michael@0 | 23 | static const wchar_t* __wfalse_name = L"false"; |
michael@0 | 24 | |
michael@0 | 25 | typedef struct _Locale_codecvt { |
michael@0 | 26 | _Locale_lcid_t lc; |
michael@0 | 27 | UINT cp; |
michael@0 | 28 | unsigned char cleads[256 / CHAR_BIT]; |
michael@0 | 29 | unsigned char max_char_size; |
michael@0 | 30 | DWORD mbtowc_flags; |
michael@0 | 31 | DWORD wctomb_flags; |
michael@0 | 32 | } _Locale_codecvt_t; |
michael@0 | 33 | |
michael@0 | 34 | /* Ctype */ |
michael@0 | 35 | _Locale_mask_t _WLocale_ctype(_Locale_ctype_t* ltype, wint_t c, |
michael@0 | 36 | _Locale_mask_t which_bits) { |
michael@0 | 37 | wchar_t buf[2]; |
michael@0 | 38 | WORD out[2]; |
michael@0 | 39 | buf[0] = c; buf[1] = 0; |
michael@0 | 40 | GetStringTypeW(CT_CTYPE1, buf, -1, out); |
michael@0 | 41 | _STLP_MARK_PARAMETER_AS_UNUSED(ltype) |
michael@0 | 42 | return (_Locale_mask_t)(MapCtypeMask(out[0]) & which_bits); |
michael@0 | 43 | } |
michael@0 | 44 | |
michael@0 | 45 | wint_t _WLocale_tolower(_Locale_ctype_t* ltype, wint_t c) { |
michael@0 | 46 | wchar_t in_c = c; |
michael@0 | 47 | wchar_t res; |
michael@0 | 48 | |
michael@0 | 49 | LCMapStringW(ltype->lc.id, LCMAP_LOWERCASE, &in_c, 1, &res, 1); |
michael@0 | 50 | return res; |
michael@0 | 51 | } |
michael@0 | 52 | |
michael@0 | 53 | wint_t _WLocale_toupper(_Locale_ctype_t* ltype, wint_t c) { |
michael@0 | 54 | wchar_t in_c = c; |
michael@0 | 55 | wchar_t res; |
michael@0 | 56 | |
michael@0 | 57 | LCMapStringW(ltype->lc.id, LCMAP_UPPERCASE, &in_c, 1, &res, 1); |
michael@0 | 58 | return res; |
michael@0 | 59 | } |
michael@0 | 60 | |
michael@0 | 61 | _Locale_codecvt_t* _Locale_codecvt_create(const char * name, _Locale_lcid_t* lc_hint, int *__err_code) { |
michael@0 | 62 | char cp_name[MAX_CP_LEN + 1]; |
michael@0 | 63 | unsigned char *ptr; |
michael@0 | 64 | CPINFO CPInfo; |
michael@0 | 65 | int i; |
michael@0 | 66 | |
michael@0 | 67 | _Locale_codecvt_t *lcodecvt = (_Locale_codecvt_t*)malloc(sizeof(_Locale_codecvt_t)); |
michael@0 | 68 | |
michael@0 | 69 | if (!lcodecvt) { *__err_code = _STLP_LOC_NO_MEMORY; return lcodecvt; } |
michael@0 | 70 | memset(lcodecvt, 0, sizeof(_Locale_codecvt_t)); |
michael@0 | 71 | |
michael@0 | 72 | if (__GetLCIDFromName(name, &lcodecvt->lc.id, cp_name, lc_hint) == -1) |
michael@0 | 73 | { free(lcodecvt); *__err_code = _STLP_LOC_UNKNOWN_NAME; return NULL; } |
michael@0 | 74 | |
michael@0 | 75 | lcodecvt->cp = atoi(cp_name); |
michael@0 | 76 | if (!GetCPInfo(lcodecvt->cp, &CPInfo)) { free(lcodecvt); return NULL; } |
michael@0 | 77 | |
michael@0 | 78 | if (lcodecvt->cp != CP_UTF7 && lcodecvt->cp != CP_UTF8) { |
michael@0 | 79 | lcodecvt->mbtowc_flags = MB_PRECOMPOSED; |
michael@0 | 80 | lcodecvt->wctomb_flags = WC_COMPOSITECHECK | WC_SEPCHARS; |
michael@0 | 81 | } |
michael@0 | 82 | lcodecvt->max_char_size = CPInfo.MaxCharSize; |
michael@0 | 83 | |
michael@0 | 84 | if (CPInfo.MaxCharSize > 1) { |
michael@0 | 85 | for (ptr = (unsigned char*)CPInfo.LeadByte; *ptr && *(ptr + 1); ptr += 2) |
michael@0 | 86 | for (i = *ptr; i <= *(ptr + 1); ++i) lcodecvt->cleads[i / CHAR_BIT] |= (0x01 << i % CHAR_BIT); |
michael@0 | 87 | } |
michael@0 | 88 | |
michael@0 | 89 | return lcodecvt; |
michael@0 | 90 | } |
michael@0 | 91 | |
michael@0 | 92 | char const* _Locale_codecvt_name(const _Locale_codecvt_t* lcodecvt, char* buf) { |
michael@0 | 93 | char cp_buf[MAX_CP_LEN + 1]; |
michael@0 | 94 | my_ltoa(lcodecvt->cp, cp_buf); |
michael@0 | 95 | return __GetLocaleName(lcodecvt->lc.id, cp_buf, buf); |
michael@0 | 96 | } |
michael@0 | 97 | |
michael@0 | 98 | void _Locale_codecvt_destroy(_Locale_codecvt_t* lcodecvt) { |
michael@0 | 99 | if (!lcodecvt) return; |
michael@0 | 100 | |
michael@0 | 101 | free(lcodecvt); |
michael@0 | 102 | } |
michael@0 | 103 | |
michael@0 | 104 | int _WLocale_mb_cur_max (_Locale_codecvt_t * lcodecvt) |
michael@0 | 105 | { return lcodecvt->max_char_size; } |
michael@0 | 106 | |
michael@0 | 107 | int _WLocale_mb_cur_min (_Locale_codecvt_t *lcodecvt) { |
michael@0 | 108 | _STLP_MARK_PARAMETER_AS_UNUSED(lcodecvt) |
michael@0 | 109 | return 1; |
michael@0 | 110 | } |
michael@0 | 111 | |
michael@0 | 112 | int _WLocale_is_stateless (_Locale_codecvt_t * lcodecvt) |
michael@0 | 113 | { return (lcodecvt->max_char_size == 1) ? 1 : 0; } |
michael@0 | 114 | |
michael@0 | 115 | static int __isleadbyte(int i, unsigned char *ctable) { |
michael@0 | 116 | unsigned char c = (unsigned char)i; |
michael@0 | 117 | return (ctable[c / CHAR_BIT] & (0x01 << c % CHAR_BIT)); |
michael@0 | 118 | } |
michael@0 | 119 | |
michael@0 | 120 | static int __mbtowc(_Locale_codecvt_t *l, wchar_t *dst, const char *from, unsigned int count) { |
michael@0 | 121 | int result; |
michael@0 | 122 | |
michael@0 | 123 | if (l->cp == CP_UTF7 || l->cp == CP_UTF8) { |
michael@0 | 124 | result = MultiByteToWideChar(l->cp, l->mbtowc_flags, from, count, dst, 1); |
michael@0 | 125 | if (result == 0) { |
michael@0 | 126 | switch (GetLastError()) { |
michael@0 | 127 | case ERROR_NO_UNICODE_TRANSLATION: |
michael@0 | 128 | return -2; |
michael@0 | 129 | default: |
michael@0 | 130 | return -1; |
michael@0 | 131 | } |
michael@0 | 132 | } |
michael@0 | 133 | } |
michael@0 | 134 | else { |
michael@0 | 135 | if (count == 1 && __isleadbyte(*from, l->cleads)) return (size_t)-2; |
michael@0 | 136 | result = MultiByteToWideChar(l->cp, l->mbtowc_flags, from, count, dst, 1); |
michael@0 | 137 | if (result == 0) return -1; |
michael@0 | 138 | } |
michael@0 | 139 | |
michael@0 | 140 | return result; |
michael@0 | 141 | } |
michael@0 | 142 | |
michael@0 | 143 | size_t _WLocale_mbtowc(_Locale_codecvt_t *lcodecvt, wchar_t *to, |
michael@0 | 144 | const char *from, size_t n, mbstate_t *shift_state) { |
michael@0 | 145 | int result; |
michael@0 | 146 | _STLP_MARK_PARAMETER_AS_UNUSED(shift_state) |
michael@0 | 147 | if (lcodecvt->max_char_size == 1) { /* Single byte encoding. */ |
michael@0 | 148 | result = MultiByteToWideChar(lcodecvt->cp, lcodecvt->mbtowc_flags, from, 1, to, 1); |
michael@0 | 149 | if (result == 0) return (size_t)-1; |
michael@0 | 150 | return result; |
michael@0 | 151 | } |
michael@0 | 152 | else { /* Multi byte encoding. */ |
michael@0 | 153 | int retval; |
michael@0 | 154 | unsigned int count = 1; |
michael@0 | 155 | while (n--) { |
michael@0 | 156 | retval = __mbtowc(lcodecvt, to, from, count); |
michael@0 | 157 | if (retval == -2) |
michael@0 | 158 | { if (++count > ((unsigned int)lcodecvt->max_char_size)) return (size_t)-1; } |
michael@0 | 159 | else if (retval == -1) |
michael@0 | 160 | { return (size_t)-1; } |
michael@0 | 161 | else |
michael@0 | 162 | { return count; } |
michael@0 | 163 | } |
michael@0 | 164 | return (size_t)-2; |
michael@0 | 165 | } |
michael@0 | 166 | } |
michael@0 | 167 | |
michael@0 | 168 | size_t _WLocale_wctomb(_Locale_codecvt_t *lcodecvt, char *to, size_t n, |
michael@0 | 169 | const wchar_t c, mbstate_t *shift_state) { |
michael@0 | 170 | int size = WideCharToMultiByte(lcodecvt->cp, lcodecvt->wctomb_flags, &c, 1, NULL, 0, NULL, NULL); |
michael@0 | 171 | |
michael@0 | 172 | if (!size) return (size_t)-1; |
michael@0 | 173 | if ((size_t)size > n) return (size_t)-2; |
michael@0 | 174 | |
michael@0 | 175 | if (n > INT_MAX) |
michael@0 | 176 | /* Limiting the output buf size to INT_MAX seems like reasonable to transform a single wchar_t. */ |
michael@0 | 177 | n = INT_MAX; |
michael@0 | 178 | |
michael@0 | 179 | WideCharToMultiByte(lcodecvt->cp, lcodecvt->wctomb_flags, &c, 1, to, (int)n, NULL, NULL); |
michael@0 | 180 | |
michael@0 | 181 | _STLP_MARK_PARAMETER_AS_UNUSED(shift_state) |
michael@0 | 182 | return (size_t)size; |
michael@0 | 183 | } |
michael@0 | 184 | |
michael@0 | 185 | size_t _WLocale_unshift(_Locale_codecvt_t *lcodecvt, mbstate_t *st, |
michael@0 | 186 | char *buf, size_t n, char **next) { |
michael@0 | 187 | /* _WLocale_wctomb do not even touch to st, there is nothing to unshift in this localization implementation. */ |
michael@0 | 188 | _STLP_MARK_PARAMETER_AS_UNUSED(lcodecvt) |
michael@0 | 189 | _STLP_MARK_PARAMETER_AS_UNUSED(st) |
michael@0 | 190 | _STLP_MARK_PARAMETER_AS_UNUSED(&n) |
michael@0 | 191 | *next = buf; |
michael@0 | 192 | return 0; |
michael@0 | 193 | } |
michael@0 | 194 | |
michael@0 | 195 | /* Collate */ |
michael@0 | 196 | /* This function takes care of the potential size_t DWORD different size. */ |
michael@0 | 197 | static int _WLocale_strcmp_aux(_Locale_collate_t* lcol, |
michael@0 | 198 | const wchar_t* s1, size_t n1, |
michael@0 | 199 | const wchar_t* s2, size_t n2) { |
michael@0 | 200 | int result = CSTR_EQUAL; |
michael@0 | 201 | while (n1 > 0 || n2 > 0) { |
michael@0 | 202 | DWORD size1 = trim_size_t_to_DWORD(n1); |
michael@0 | 203 | DWORD size2 = trim_size_t_to_DWORD(n2); |
michael@0 | 204 | result = CompareStringW(lcol->lc.id, 0, s1, size1, s2, size2); |
michael@0 | 205 | if (result != CSTR_EQUAL) |
michael@0 | 206 | break; |
michael@0 | 207 | n1 -= size1; |
michael@0 | 208 | n2 -= size2; |
michael@0 | 209 | } |
michael@0 | 210 | return result; |
michael@0 | 211 | } |
michael@0 | 212 | |
michael@0 | 213 | int _WLocale_strcmp(_Locale_collate_t* lcol, |
michael@0 | 214 | const wchar_t* s1, size_t n1, |
michael@0 | 215 | const wchar_t* s2, size_t n2) { |
michael@0 | 216 | int result; |
michael@0 | 217 | result = _WLocale_strcmp_aux(lcol, s1, n1, s2, n2); |
michael@0 | 218 | return (result == CSTR_EQUAL) ? 0 : (result == CSTR_LESS_THAN) ? -1 : 1; |
michael@0 | 219 | } |
michael@0 | 220 | |
michael@0 | 221 | size_t _WLocale_strxfrm(_Locale_collate_t* lcol, |
michael@0 | 222 | wchar_t* dst, size_t dst_size, |
michael@0 | 223 | const wchar_t* src, size_t src_size) { |
michael@0 | 224 | int result, i; |
michael@0 | 225 | |
michael@0 | 226 | /* see _Locale_strxfrm: */ |
michael@0 | 227 | if (src_size > INT_MAX) { |
michael@0 | 228 | if (dst != 0) { |
michael@0 | 229 | _STLP_WCSNCPY(dst, dst_size, src, src_size); |
michael@0 | 230 | } |
michael@0 | 231 | return src_size; |
michael@0 | 232 | } |
michael@0 | 233 | if (dst_size > INT_MAX) { |
michael@0 | 234 | dst_size = INT_MAX; |
michael@0 | 235 | } |
michael@0 | 236 | result = LCMapStringW(lcol->lc.id, LCMAP_SORTKEY, src, (int)src_size, dst, (int)dst_size); |
michael@0 | 237 | if (result != 0 && dst != 0) { |
michael@0 | 238 | for (i = result - 1; i >= 0; --i) { |
michael@0 | 239 | dst[i] = ((unsigned char*)dst)[i]; |
michael@0 | 240 | } |
michael@0 | 241 | } |
michael@0 | 242 | return result != 0 ? result - 1 : 0; |
michael@0 | 243 | } |
michael@0 | 244 | |
michael@0 | 245 | /* Numeric */ |
michael@0 | 246 | wchar_t _WLocale_decimal_point(_Locale_numeric_t* lnum) { |
michael@0 | 247 | wchar_t buf[4]; |
michael@0 | 248 | GetLocaleInfoW(lnum->lc.id, LOCALE_SDECIMAL, buf, 4); |
michael@0 | 249 | return buf[0]; |
michael@0 | 250 | } |
michael@0 | 251 | |
michael@0 | 252 | wchar_t _WLocale_thousands_sep(_Locale_numeric_t* lnum) { |
michael@0 | 253 | wchar_t buf[4]; |
michael@0 | 254 | GetLocaleInfoW(lnum->lc.id, LOCALE_STHOUSAND, buf, 4); |
michael@0 | 255 | return buf[0]; |
michael@0 | 256 | } |
michael@0 | 257 | |
michael@0 | 258 | const wchar_t * _WLocale_true(_Locale_numeric_t* lnum, wchar_t* buf, size_t bufSize) { |
michael@0 | 259 | _STLP_MARK_PARAMETER_AS_UNUSED(lnum) |
michael@0 | 260 | _STLP_MARK_PARAMETER_AS_UNUSED(buf) |
michael@0 | 261 | _STLP_MARK_PARAMETER_AS_UNUSED(&bufSize) |
michael@0 | 262 | return __wtrue_name; |
michael@0 | 263 | } |
michael@0 | 264 | |
michael@0 | 265 | const wchar_t * _WLocale_false(_Locale_numeric_t* lnum, wchar_t* buf, size_t bufSize) { |
michael@0 | 266 | _STLP_MARK_PARAMETER_AS_UNUSED(lnum) |
michael@0 | 267 | _STLP_MARK_PARAMETER_AS_UNUSED(buf) |
michael@0 | 268 | _STLP_MARK_PARAMETER_AS_UNUSED(&bufSize) |
michael@0 | 269 | return __wfalse_name; |
michael@0 | 270 | } |
michael@0 | 271 | |
michael@0 | 272 | /* Monetary */ |
michael@0 | 273 | const wchar_t* _WLocale_int_curr_symbol(_Locale_monetary_t * lmon, wchar_t* buf, size_t bufSize) |
michael@0 | 274 | { GetLocaleInfoW(lmon->lc.id, LOCALE_SINTLSYMBOL, buf, (int)bufSize); return buf; } |
michael@0 | 275 | |
michael@0 | 276 | const wchar_t* _WLocale_currency_symbol(_Locale_monetary_t * lmon, wchar_t* buf, size_t bufSize) |
michael@0 | 277 | { GetLocaleInfoW(lmon->lc.id, LOCALE_SCURRENCY, buf, (int)bufSize); return buf; } |
michael@0 | 278 | |
michael@0 | 279 | wchar_t _WLocale_mon_decimal_point(_Locale_monetary_t * lmon) |
michael@0 | 280 | { return lmon->decimal_point[0]; } |
michael@0 | 281 | |
michael@0 | 282 | wchar_t _WLocale_mon_thousands_sep(_Locale_monetary_t * lmon) |
michael@0 | 283 | { return lmon->thousands_sep[0]; } |
michael@0 | 284 | |
michael@0 | 285 | const wchar_t* _WLocale_positive_sign(_Locale_monetary_t * lmon, wchar_t* buf, size_t bufSize) |
michael@0 | 286 | { GetLocaleInfoW(lmon->lc.id, LOCALE_SPOSITIVESIGN, buf, (int)bufSize); return buf; } |
michael@0 | 287 | |
michael@0 | 288 | const wchar_t* _WLocale_negative_sign(_Locale_monetary_t * lmon, wchar_t* buf, size_t bufSize) |
michael@0 | 289 | { GetLocaleInfoW(lmon->lc.id, LOCALE_SNEGATIVESIGN, buf, (int)bufSize); return buf; } |
michael@0 | 290 | |
michael@0 | 291 | /* Time */ |
michael@0 | 292 | const wchar_t * _WLocale_full_monthname(_Locale_time_t * ltime, int month, |
michael@0 | 293 | wchar_t* buf, size_t bufSize) |
michael@0 | 294 | { GetLocaleInfoW(ltime->lc.id, LOCALE_SMONTHNAME1 + month, buf, (int)bufSize); return buf; } |
michael@0 | 295 | |
michael@0 | 296 | const wchar_t * _WLocale_abbrev_monthname(_Locale_time_t * ltime, int month, |
michael@0 | 297 | wchar_t* buf, size_t bufSize) |
michael@0 | 298 | { GetLocaleInfoW(ltime->lc.id, LOCALE_SABBREVMONTHNAME1 + month, buf, (int)bufSize); return buf; } |
michael@0 | 299 | |
michael@0 | 300 | const wchar_t * _WLocale_full_dayofweek(_Locale_time_t * ltime, int day, |
michael@0 | 301 | wchar_t* buf, size_t bufSize) |
michael@0 | 302 | { GetLocaleInfoW(ltime->lc.id, LOCALE_SDAYNAME1 + day, buf, (int)bufSize); return buf; } |
michael@0 | 303 | |
michael@0 | 304 | const wchar_t * _WLocale_abbrev_dayofweek(_Locale_time_t * ltime, int day, |
michael@0 | 305 | wchar_t* buf, size_t bufSize) |
michael@0 | 306 | { GetLocaleInfoW(ltime->lc.id, LOCALE_SABBREVDAYNAME1 + day, buf, (int)bufSize); return buf; } |
michael@0 | 307 | |
michael@0 | 308 | const wchar_t* _WLocale_am_str(_Locale_time_t* ltime, |
michael@0 | 309 | wchar_t* buf, size_t bufSize) |
michael@0 | 310 | { GetLocaleInfoW(ltime->lc.id, LOCALE_S1159, buf, (int)bufSize); return buf; } |
michael@0 | 311 | |
michael@0 | 312 | const wchar_t* _WLocale_pm_str(_Locale_time_t* ltime, |
michael@0 | 313 | wchar_t* buf, size_t bufSize) |
michael@0 | 314 | { GetLocaleInfoW(ltime->lc.id, LOCALE_S2359, buf, (int)bufSize); return buf; } |