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.
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
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/. */
7 /*
8 * Date functions used by tests in Date suite
9 *
10 */
11 var msPerDay = 86400000;
12 var HoursPerDay = 24;
13 var MinutesPerHour = 60;
14 var SecondsPerMinute = 60;
15 var msPerSecond = 1000;
16 var msPerMinute = 60000; // msPerSecond * SecondsPerMinute
17 var msPerHour = 3600000; // msPerMinute * MinutesPerHour
18 var TZ_DIFF = getTimeZoneDiff(); // offset of tester's timezone from UTC
19 var TZ_ADJUST = TZ_DIFF * msPerHour;
20 var TZ_PST = -8; // offset of Pacific Standard Time from UTC
21 var PST_DIFF = TZ_DIFF - TZ_PST; // offset of tester's timezone from PST
22 var TIME_1970 = 0;
23 var TIME_2000 = 946684800000;
24 var TIME_1900 = -2208988800000;
25 var UTC_29_FEB_2000 = TIME_2000 + 31*msPerDay + 28*msPerDay;
26 var UTC_1_JAN_2005 = TIME_2000 + TimeInYear(2000) + TimeInYear(2001) +
27 TimeInYear(2002) + TimeInYear(2003) + TimeInYear(2004);
28 var now = new Date();
29 var TIME_NOW = now.valueOf(); //valueOf() is to accurate to the millisecond
30 //Date.parse() is accurate only to the second
32 /*
33 * Originally, the test suite used a hard-coded value TZ_DIFF = -8.
34 * But that was only valid for testers in the Pacific Standard Time Zone!
35 * We calculate the proper number dynamically for any tester. We just
36 * have to be careful not to use a date subject to Daylight Savings Time...
37 */
38 function getTimeZoneDiff()
39 {
40 return -((new Date(2000, 1, 1)).getTimezoneOffset())/60;
41 }
44 /*
45 * Date test "ResultArrays" are hard-coded for Pacific Standard Time.
46 * We must adjust them for the tester's own timezone -
47 */
48 function adjustResultArray(ResultArray, msMode)
49 {
50 // If the tester's system clock is in PST, no need to continue -
51 if (!PST_DIFF) {return;}
53 /* The date testcases instantiate Date objects in two different ways:
54 *
55 * millisecond mode: e.g. dt = new Date(10000000);
56 * year-month-day mode: dt = new Date(2000, 5, 1, ...);
57 *
58 * In the first case, the date is measured from Time 0 in Greenwich (i.e. UTC).
59 * In the second case, it is measured with reference to the tester's local timezone.
60 *
61 * In the first case we must correct those values expected for local measurements,
62 * like dt.getHours() etc. No correction is necessary for dt.getUTCHours() etc.
63 *
64 * In the second case, it is exactly the other way around -
65 */
66 if (msMode)
67 {
68 // The hard-coded UTC milliseconds from Time 0 derives from a UTC date.
69 // Shift to the right by the offset between UTC and the tester.
70 var t = ResultArray[TIME] + TZ_DIFF*msPerHour;
72 // Use our date arithmetic functions to determine the local hour, day, etc.
73 ResultArray[HOURS] = HourFromTime(t);
74 ResultArray[DAY] = WeekDay(t);
75 ResultArray[DATE] = DateFromTime(t);
76 ResultArray[MONTH] = MonthFromTime(t);
77 ResultArray[YEAR] = YearFromTime(t);
78 }
79 else
80 {
81 // The hard-coded UTC milliseconds from Time 0 derives from a PST date.
82 // Shift to the left by the offset between PST and the tester.
83 var t = ResultArray[TIME] - PST_DIFF*msPerHour;
85 // Use our date arithmetic functions to determine the UTC hour, day, etc.
86 ResultArray[TIME] = t;
87 ResultArray[UTC_HOURS] = HourFromTime(t);
88 ResultArray[UTC_DAY] = WeekDay(t);
89 ResultArray[UTC_DATE] = DateFromTime(t);
90 ResultArray[UTC_MONTH] = MonthFromTime(t);
91 ResultArray[UTC_YEAR] = YearFromTime(t);
92 }
93 }
96 function Day( t ) {
97 return ( Math.floor(t/msPerDay ) );
98 }
99 function DaysInYear( y ) {
100 if ( y % 4 != 0 ) {
101 return 365;
102 }
103 if ( (y % 4 == 0) && (y % 100 != 0) ) {
104 return 366;
105 }
106 if ( (y % 100 == 0) && (y % 400 != 0) ) {
107 return 365;
108 }
109 if ( (y % 400 == 0) ){
110 return 366;
111 } else {
112 return "ERROR: DaysInYear(" + y + ") case not covered";
113 }
114 }
115 function TimeInYear( y ) {
116 return ( DaysInYear(y) * msPerDay );
117 }
118 function DayNumber( t ) {
119 return ( Math.floor( t / msPerDay ) );
120 }
121 function TimeWithinDay( t ) {
123 var r = t % msPerDay;
125 if (r < 0)
126 {
127 r += msPerDay;
128 }
129 return r;
131 }
132 function YearNumber( t ) {
133 }
134 function TimeFromYear( y ) {
135 return ( msPerDay * DayFromYear(y) );
136 }
137 function DayFromYear( y ) {
138 return ( 365*(y-1970) +
139 Math.floor((y-1969)/4) -
140 Math.floor((y-1901)/100) +
141 Math.floor((y-1601)/400) );
142 }
143 function InLeapYear( t ) {
144 if ( DaysInYear(YearFromTime(t)) == 365 ) {
145 return 0;
146 }
147 if ( DaysInYear(YearFromTime(t)) == 366 ) {
148 return 1;
149 } else {
150 return "ERROR: InLeapYear("+ t + ") case not covered";
151 }
152 }
153 function YearFromTime( t ) {
154 t = Number( t );
155 var sign = ( t < 0 ) ? -1 : 1;
156 var year = ( sign < 0 ) ? 1969 : 1970;
157 for ( var timeToTimeZero = t; ; ) {
158 // subtract the current year's time from the time that's left.
159 timeToTimeZero -= sign * TimeInYear(year)
161 // if there's less than the current year's worth of time left, then break.
162 if ( sign < 0 ) {
163 if ( sign * timeToTimeZero <= 0 ) {
164 break;
165 } else {
166 year += sign;
167 }
168 } else {
169 if ( sign * timeToTimeZero < 0 ) {
170 break;
171 } else {
172 year += sign;
173 }
174 }
175 }
176 return ( year );
177 }
178 function MonthFromTime( t ) {
179 // i know i could use switch but i'd rather not until it's part of ECMA
180 var day = DayWithinYear( t );
181 var leap = InLeapYear(t);
183 if ( (0 <= day) && (day < 31) ) {
184 return 0;
185 }
186 if ( (31 <= day) && (day < (59+leap)) ) {
187 return 1;
188 }
189 if ( ((59+leap) <= day) && (day < (90+leap)) ) {
190 return 2;
191 }
192 if ( ((90+leap) <= day) && (day < (120+leap)) ) {
193 return 3;
194 }
195 if ( ((120+leap) <= day) && (day < (151+leap)) ) {
196 return 4;
197 }
198 if ( ((151+leap) <= day) && (day < (181+leap)) ) {
199 return 5;
200 }
201 if ( ((181+leap) <= day) && (day < (212+leap)) ) {
202 return 6;
203 }
204 if ( ((212+leap) <= day) && (day < (243+leap)) ) {
205 return 7;
206 }
207 if ( ((243+leap) <= day) && (day < (273+leap)) ) {
208 return 8;
209 }
210 if ( ((273+leap) <= day) && (day < (304+leap)) ) {
211 return 9;
212 }
213 if ( ((304+leap) <= day) && (day < (334+leap)) ) {
214 return 10;
215 }
216 if ( ((334+leap) <= day) && (day < (365+leap)) ) {
217 return 11;
218 } else {
219 return "ERROR: MonthFromTime("+t+") not known";
220 }
221 }
222 function DayWithinYear( t ) {
223 return( Day(t) - DayFromYear(YearFromTime(t)));
224 }
225 function DateFromTime( t ) {
226 var day = DayWithinYear(t);
227 var month = MonthFromTime(t);
229 if ( month == 0 ) {
230 return ( day + 1 );
231 }
232 if ( month == 1 ) {
233 return ( day - 30 );
234 }
235 if ( month == 2 ) {
236 return ( day - 58 - InLeapYear(t) );
237 }
238 if ( month == 3 ) {
239 return ( day - 89 - InLeapYear(t));
240 }
241 if ( month == 4 ) {
242 return ( day - 119 - InLeapYear(t));
243 }
244 if ( month == 5 ) {
245 return ( day - 150- InLeapYear(t));
246 }
247 if ( month == 6 ) {
248 return ( day - 180- InLeapYear(t));
249 }
250 if ( month == 7 ) {
251 return ( day - 211- InLeapYear(t));
252 }
253 if ( month == 8 ) {
254 return ( day - 242- InLeapYear(t));
255 }
256 if ( month == 9 ) {
257 return ( day - 272- InLeapYear(t));
258 }
259 if ( month == 10 ) {
260 return ( day - 303- InLeapYear(t));
261 }
262 if ( month == 11 ) {
263 return ( day - 333- InLeapYear(t));
264 }
266 return ("ERROR: DateFromTime("+t+") not known" );
267 }
268 function WeekDay( t ) {
269 var weekday = (Day(t)+4) % 7;
270 return( weekday < 0 ? 7 + weekday : weekday );
271 }
273 // missing daylight savings time adjustment
275 function HourFromTime( t ) {
276 var h = Math.floor( t / msPerHour ) % HoursPerDay;
277 return ( (h<0) ? HoursPerDay + h : h );
278 }
279 function MinFromTime( t ) {
280 var min = Math.floor( t / msPerMinute ) % MinutesPerHour;
281 return( ( min < 0 ) ? MinutesPerHour + min : min );
282 }
283 function SecFromTime( t ) {
284 var sec = Math.floor( t / msPerSecond ) % SecondsPerMinute;
285 return ( (sec < 0 ) ? SecondsPerMinute + sec : sec );
286 }
287 function msFromTime( t ) {
288 var ms = t % msPerSecond;
289 return ( (ms < 0 ) ? msPerSecond + ms : ms );
290 }
291 function LocalTZA() {
292 return ( TZ_DIFF * msPerHour );
293 }
294 function UTC( t ) {
295 return ( t - LocalTZA() - DaylightSavingTA(t - LocalTZA()) );
296 }
298 function DaylightSavingTA( t ) {
299 t = t - LocalTZA();
301 var dst_start = GetDSTStart(t);
302 var dst_end = GetDSTEnd(t);
304 if ( t >= dst_start && t < dst_end )
305 return msPerHour;
307 return 0;
308 }
310 function GetFirstSundayInMonth( t, m ) {
311 var year = YearFromTime(t);
312 var leap = InLeapYear(t);
314 // month m 0..11
315 // april == 3
316 // march == 2
318 // set time to first day of month m
319 var time = TimeFromYear(year);
320 for (var i = 0; i < m; ++i)
321 {
322 time += TimeInMonth(i, leap);
323 }
325 for ( var first_sunday = time; WeekDay(first_sunday) > 0;
326 first_sunday += msPerDay )
327 {
328 ;
329 }
331 return first_sunday;
332 }
334 function GetLastSundayInMonth( t, m ) {
335 var year = YearFromTime(t);
336 var leap = InLeapYear(t);
338 // month m 0..11
339 // april == 3
340 // march == 2
342 // first day of following month
343 var time = TimeFromYear(year);
344 for (var i = 0; i <= m; ++i)
345 {
346 time += TimeInMonth(i, leap);
347 }
348 // prev day == last day of month
349 time -= msPerDay;
351 for ( var last_sunday = time; WeekDay(last_sunday) > 0;
352 last_sunday -= msPerDay )
353 {
354 ;
355 }
356 return last_sunday;
357 }
359 /*
360 15.9.1.9 Daylight Saving Time Adjustment
362 The implementation of ECMAScript should not try to determine whether
363 the exact time was subject to daylight saving time, but just whether
364 daylight saving time would have been in effect if the current
365 daylight saving time algorithm had been used at the time. This avoids
366 complications such as taking into account the years that the locale
367 observed daylight saving time year round.
368 */
370 /*
371 US DST algorithm
373 Before 2007, DST starts first Sunday in April at 2 AM and ends last
374 Sunday in October at 2 AM
376 Starting in 2007, DST starts second Sunday in March at 2 AM and ends
377 first Sunday in November at 2 AM
379 Note that different operating systems behave differently.
381 Fully patched Windows XP uses the 2007 algorithm for all dates while
382 fully patched Fedora Core 6 and RHEL 4 Linux use the algorithm in
383 effect at the time.
385 Since pre-2007 DST is a subset of 2007 DST rules, this only affects
386 tests that occur in the period Mar-Apr and Oct-Nov where the two
387 algorithms do not agree.
389 */
391 function GetDSTStart( t )
392 {
393 return (GetFirstSundayInMonth(t, 2) + 7*msPerDay + 2*msPerHour - LocalTZA());
394 }
396 function GetDSTEnd( t )
397 {
398 return (GetFirstSundayInMonth(t, 10) + 2*msPerHour - LocalTZA());
399 }
401 function GetOldDSTStart( t )
402 {
403 return (GetFirstSundayInMonth(t, 3) + 2*msPerHour - LocalTZA());
404 }
406 function GetOldDSTEnd( t )
407 {
408 return (GetLastSundayInMonth(t, 9) + 2*msPerHour - LocalTZA());
409 }
411 function LocalTime( t ) {
412 return ( t + LocalTZA() + DaylightSavingTA(t) );
413 }
414 function MakeTime( hour, min, sec, ms ) {
415 if ( isNaN( hour ) || isNaN( min ) || isNaN( sec ) || isNaN( ms ) ) {
416 return Number.NaN;
417 }
419 hour = ToInteger(hour);
420 min = ToInteger( min);
421 sec = ToInteger( sec);
422 ms = ToInteger( ms );
424 return( (hour*msPerHour) + (min*msPerMinute) +
425 (sec*msPerSecond) + ms );
426 }
427 function MakeDay( year, month, date ) {
428 if ( isNaN(year) || isNaN(month) || isNaN(date) ) {
429 return Number.NaN;
430 }
431 year = ToInteger(year);
432 month = ToInteger(month);
433 date = ToInteger(date );
435 var sign = ( year < 1970 ) ? -1 : 1;
436 var t = ( year < 1970 ) ? 1 : 0;
437 var y = ( year < 1970 ) ? 1969 : 1970;
439 var result5 = year + Math.floor( month/12 );
440 var result6 = month % 12;
442 if ( year < 1970 ) {
443 for ( y = 1969; y >= year; y += sign ) {
444 t += sign * TimeInYear(y);
445 }
446 } else {
447 for ( y = 1970 ; y < year; y += sign ) {
448 t += sign * TimeInYear(y);
449 }
450 }
452 var leap = InLeapYear( t );
454 for ( var m = 0; m < month; m++ ) {
455 t += TimeInMonth( m, leap );
456 }
458 if ( YearFromTime(t) != result5 ) {
459 return Number.NaN;
460 }
461 if ( MonthFromTime(t) != result6 ) {
462 return Number.NaN;
463 }
464 if ( DateFromTime(t) != 1 ) {
465 return Number.NaN;
466 }
468 return ( (Day(t)) + date - 1 );
469 }
470 function TimeInMonth( month, leap ) {
471 // september april june november
472 // jan 0 feb 1 mar 2 apr 3 may 4 june 5 jul 6
473 // aug 7 sep 8 oct 9 nov 10 dec 11
475 if ( month == 3 || month == 5 || month == 8 || month == 10 ) {
476 return ( 30*msPerDay );
477 }
479 // all the rest
480 if ( month == 0 || month == 2 || month == 4 || month == 6 ||
481 month == 7 || month == 9 || month == 11 ) {
482 return ( 31*msPerDay );
483 }
485 // save february
486 return ( (leap == 0) ? 28*msPerDay : 29*msPerDay );
487 }
488 function MakeDate( day, time ) {
489 if ( day == Number.POSITIVE_INFINITY ||
490 day == Number.NEGATIVE_INFINITY ) {
491 return Number.NaN;
492 }
493 if ( time == Number.POSITIVE_INFINITY ||
494 time == Number.NEGATIVE_INFINITY ) {
495 return Number.NaN;
496 }
497 return ( day * msPerDay ) + time;
498 }
499 function TimeClip( t ) {
500 if ( isNaN( t ) ) {
501 return ( Number.NaN );
502 }
503 if ( Math.abs( t ) > 8.64e15 ) {
504 return ( Number.NaN );
505 }
507 return ( ToInteger( t ) );
508 }
509 function ToInteger( t ) {
510 t = Number( t );
512 if ( isNaN( t ) ){
513 return ( Number.NaN );
514 }
515 if ( t == 0 || t == -0 ||
516 t == Number.POSITIVE_INFINITY || t == Number.NEGATIVE_INFINITY ) {
517 return 0;
518 }
520 var sign = ( t < 0 ) ? -1 : 1;
522 return ( sign * Math.floor( Math.abs( t ) ) );
523 }
524 function Enumerate ( o ) {
525 var p;
526 for ( p in o ) {
527 print( p +": " + o[p] );
528 }
529 }