Skip to content

Commit

Permalink
Made separate tests for each TZ type
Browse files Browse the repository at this point in the history
Fixed handling of unserializing types 1 and 3
  • Loading branch information
Lonny Kapelushnik committed Jan 14, 2013
1 parent e76aa19 commit c2e11f0
Show file tree
Hide file tree
Showing 6 changed files with 124 additions and 44 deletions.
66 changes: 33 additions & 33 deletions ext/date/lib/parse_date.re
Expand Up @@ -530,39 +530,6 @@ static timelib_ull timelib_get_unsigned_nr(char **ptr, int max_length)
return dir * timelib_get_nr(ptr, max_length);
}

static long timelib_parse_tz_cor(char **ptr)
{
char *begin = *ptr, *end;
long tmp;

while (isdigit(**ptr) || **ptr == ':') {
++*ptr;
}
end = *ptr;
switch (end - begin) {
case 1:
case 2:
return HOUR(strtol(begin, NULL, 10));
break;
case 3:
case 4:
if (begin[1] == ':') {
tmp = HOUR(strtol(begin, NULL, 10)) + strtol(begin + 2, NULL, 10);
return tmp;
} else if (begin[2] == ':') {
tmp = HOUR(strtol(begin, NULL, 10)) + strtol(begin + 3, NULL, 10);
return tmp;
} else {
tmp = strtol(begin, NULL, 10);
return HOUR(tmp / 100) + tmp % 100;
}
case 5:
tmp = HOUR(strtol(begin, NULL, 10)) + strtol(begin + 3, NULL, 10);
return tmp;
}
return 0;
}

static timelib_sll timelib_lookup_relative_text(char **ptr, int *behavior)
{
char *word;
Expand Down Expand Up @@ -2271,6 +2238,39 @@ const timelib_tz_lookup_table *timelib_timezone_abbreviations_list(void)
return timelib_timezone_lookup;
}

long timelib_parse_tz_cor(char **ptr)
{
char *begin = *ptr, *end;
long tmp;

while (isdigit(**ptr) || **ptr == ':') {
++*ptr;
}
end = *ptr;
switch (end - begin) {
case 1:
case 2:
return HOUR(strtol(begin, NULL, 10));
break;
case 3:
case 4:
if (begin[1] == ':') {
tmp = HOUR(strtol(begin, NULL, 10)) + strtol(begin + 2, NULL, 10);
return tmp;
} else if (begin[2] == ':') {
tmp = HOUR(strtol(begin, NULL, 10)) + strtol(begin + 3, NULL, 10);
return tmp;
} else {
tmp = strtol(begin, NULL, 10);
return HOUR(tmp / 100) + tmp % 100;
}
case 5:
tmp = HOUR(strtol(begin, NULL, 10)) + strtol(begin + 3, NULL, 10);
return tmp;
}
return 0;
}

#ifdef DEBUG_PARSER_STUB
int main(void)
{
Expand Down
1 change: 1 addition & 0 deletions ext/date/lib/timelib.h
Expand Up @@ -73,6 +73,7 @@ timelib_time *timelib_parse_from_format(char *format, char *s, int len, timelib_
void timelib_fill_holes(timelib_time *parsed, timelib_time *now, int options);
char *timelib_timezone_id_from_abbr(const char *abbr, long gmtoffset, int isdst);
const timelib_tz_lookup_table *timelib_timezone_abbreviations_list(void);
long timelib_parse_tz_cor(char**);

/* From parse_iso_intervals.re */
void timelib_strtointerval(char *s, int len,
Expand Down
31 changes: 20 additions & 11 deletions ext/date/php_date.c
Expand Up @@ -2210,15 +2210,15 @@ static HashTable *date_object_get_properties_timezone(zval *object TSRMLS_DC)
char *tmpstr = emalloc(sizeof("UTC+05:00"));

snprintf(tmpstr, sizeof("+05:00"), "%c%02d:%02d",
tzobj->tzi.z.utc_offset > 0 ? '-' : '+',
abs(tzobj->tzi.z.utc_offset / 60),
abs((tzobj->tzi.z.utc_offset % 60)));
tzobj->tzi.utc_offset > 0 ? '-' : '+',
abs(tzobj->tzi.utc_offset / 60),
abs((tzobj->tzi.utc_offset % 60)));

ZVAL_STRING(zv, tmpstr, 0);
}
break;
case TIMELIB_ZONETYPE_ABBR:
ZVAL_STRING(zv, tzobj->tzi.tz->timezone_abbr, 1);
ZVAL_STRING(zv, tzobj->tzi.z.abbr, 1);
break;
}
zend_hash_update(props, "timezone", 9, &zv, sizeof(zval), NULL);
Expand Down Expand Up @@ -3294,30 +3294,39 @@ static int php_date_timezone_initialize_from_hash(zval **return_value, php_timez
zval **z_timezone = NULL;
zval **z_timezone_type = NULL;
timelib_tzinfo *tzi;
char **offset;

if (zend_hash_find(myht, "timezone_type", 14, (void**) &z_timezone_type) == SUCCESS) {
if (zend_hash_find(myht, "timezone", 9, (void**) &z_timezone) == SUCCESS) {
convert_to_long(*z_timezone_type);
switch (Z_LVAL_PP(z_timezone_type)) {
case TIMELIB_ZONETYPE_OFFSET:
offset = malloc(sizeof(char) * (Z_STRLEN_PP(z_timezone) + 1));
*offset = (Z_STRVAL_PP(z_timezone));
if(**offset == '+'){
++*offset;
(*tzobj)->tzi.utc_offset = -1 * timelib_parse_tz_cor((char **)offset);
} else {
++*offset;
(*tzobj)->tzi.utc_offset = timelib_parse_tz_cor((char **)offset);
}
free(offset);
(*tzobj)->type = TIMELIB_ZONETYPE_OFFSET;
(*tzobj)->tzi.utc_offset = Z_LVAL_PP(z_timezone);
(*tzobj)->initialized = 1;
return SUCCESS;
break;
case TIMELIB_ZONETYPE_ABBR:
(*tzobj)->type = TIMELIB_ZONETYPE_ABBR;
(*tzobj)->tzi.z.utc_offset = Z_LVAL_PP(z_timezone);
break;
case TIMELIB_ZONETYPE_ID:
if (SUCCESS == timezone_initialize(&tzi, Z_STRVAL_PP(z_timezone) TSRMLS_CC)) {
(*tzobj)->type = TIMELIB_ZONETYPE_ID;
(*tzobj)->tzi.tz = tzi;
(*tzobj)->initialized = 1;
return 1;
return SUCCESS;
}
}
}
}
return 0;
return FAILURE;
}

/* {{{ proto DateTimeZone::__set_state()
Expand Down Expand Up @@ -3351,7 +3360,7 @@ PHP_METHOD(DateTimeZone, __wakeup)
tzobj = (php_timezone_obj *) zend_object_store_get_object(object TSRMLS_CC);

myht = Z_OBJPROP_P(object);

php_date_timezone_initialize_from_hash(&return_value, &tzobj, myht TSRMLS_CC);
}
/* }}} */
Expand Down
35 changes: 35 additions & 0 deletions ext/date/tests/DateTimeZone_serialize_type_1.phpt
@@ -0,0 +1,35 @@
--TEST--
Test serialization of DateTimeZone objects
--FILE--
<?php
//Set the default time zone
date_default_timezone_set("Europe/London");

$tz1 = date_create("2012-01-01 10:00 +1:00")->getTimezone();
var_dump( $tz1 );
$serialized = serialize($tz1);
var_dump($serialized);

$tz2 = unserialize($serialized);
var_dump($tz2);
// Try to use unserialzied object
var_dump( $tz2->getName() );

?>
===DONE===
--EXPECTF--
object(DateTimeZone)#%d (2) {
["timezone_type"]=>
int(1)
["timezone"]=>
string(6) "+01:00"
}
string(77) "O:12:"DateTimeZone":2:{s:13:"timezone_type";i:1;s:8:"timezone";s:6:"+01:00";}"
object(DateTimeZone)#%d (2) {
["timezone_type"]=>
int(1)
["timezone"]=>
string(6) "+01:00"
}
string(6) "+01:00"
===DONE===
35 changes: 35 additions & 0 deletions ext/date/tests/DateTimeZone_serialize_type_2.phpt
@@ -0,0 +1,35 @@
--TEST--
Test serialization of DateTimeZone objects
--FILE--
<?php
//Set the default time zone
date_default_timezone_set("Europe/London");

$tz1 = new DateTimeZone("EST");
var_dump( $tz1 );
$serialized = serialize($tz1);
var_dump($serialized);

$tz2 = unserialize($serialized);
var_dump($tz2);
// Try to use unserialzied object
var_dump( $tz2->getName() );

?>
===DONE===
--EXPECTF--
object(DateTimeZone)#%d (2) {
["timezone_type"]=>
int(3)
["timezone"]=>
string(16) "America/New_York"
}
string(88) "O:12:"DateTimeZone":2:{s:13:"timezone_type";i:3;s:8:"timezone";s:16:"America/New_York";}"
object(DateTimeZone)#%d (2) {
["timezone_type"]=>
int(3)
["timezone"]=>
string(16) "America/New_York"
}
string(16) "America/New_York"
===DONE===
File renamed without changes.

0 comments on commit c2e11f0

Please sign in to comment.