ObjFW  Check-in [804f222e18]

Overview
Comment:OFDate: Throw on trailing garbage
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 804f222e18fd56bed253a31e9e28ad47f81bb9a7c838f733b167829b0742d04b
User & Date: js on 2016-09-11 22:23:45
Other Links: manifest | tags
Context
2016-09-12
00:10
of_strptime: Fix parsing of %b check-in: 99158f978b user: js tags: trunk
2016-09-11
22:23
OFDate: Throw on trailing garbage check-in: 804f222e18 user: js tags: trunk
22:03
OFDate: Add support for parsing time zones check-in: e4439b7ef8 user: js tags: trunk
Changes

Modified src/OFDate.m from [6c84c9ff36] to [125716a7f2].

266
267
268
269
270
271
272

273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296

297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315

- initWithDateString: (OFString*)string
	      format: (OFString*)format
{
	self = [super init];

	@try {

		struct tm tm = { 0 };
		int16_t tz = 0;

		tm.tm_isdst = -1;

		if (of_strptime([string UTF8String], [format UTF8String],
		    &tm, &tz) == NULL)
			@throw [OFInvalidFormatException exception];

		_seconds = tmAndTzToTime(&tm, &tz);
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- initWithLocalDateString: (OFString*)string
		   format: (OFString*)format
{
	self = [super init];

	@try {

		struct tm tm = { 0 };
		/*
		 * of_strptime() can never set this to INT16_MAX, no matter
		 * what is passed to it, so this is a safe way to figure out if
		 * the date contains a time zone.
		 */
		int16_t tz = INT16_MAX;

		tm.tm_isdst = -1;

		if (of_strptime([string UTF8String], [format UTF8String],
		    &tm, &tz) == NULL)
			@throw [OFInvalidFormatException exception];

		if (tz == INT16_MAX) {
#ifndef OF_WINDOWS
			if ((_seconds = mktime(&tm)) == -1)
				@throw [OFInvalidFormatException exception];
#else







>





|
|

















>










|
|







266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317

- initWithDateString: (OFString*)string
	      format: (OFString*)format
{
	self = [super init];

	@try {
		const char *UTF8String = [string UTF8String];
		struct tm tm = { 0 };
		int16_t tz = 0;

		tm.tm_isdst = -1;

		if (of_strptime(UTF8String, [format UTF8String],
		    &tm, &tz) != UTF8String + [string UTF8StringLength])
			@throw [OFInvalidFormatException exception];

		_seconds = tmAndTzToTime(&tm, &tz);
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- initWithLocalDateString: (OFString*)string
		   format: (OFString*)format
{
	self = [super init];

	@try {
		const char *UTF8String = [string UTF8String];
		struct tm tm = { 0 };
		/*
		 * of_strptime() can never set this to INT16_MAX, no matter
		 * what is passed to it, so this is a safe way to figure out if
		 * the date contains a time zone.
		 */
		int16_t tz = INT16_MAX;

		tm.tm_isdst = -1;

		if (of_strptime(UTF8String, [format UTF8String],
		    &tm, &tz) != UTF8String + [string UTF8StringLength])
			@throw [OFInvalidFormatException exception];

		if (tz == INT16_MAX) {
#ifndef OF_WINDOWS
			if ((_seconds = mktime(&tm)) == -1)
				@throw [OFInvalidFormatException exception];
#else

Modified tests/OFDateTests.m from [ab5193ad47] to [d9a4b150fe].

18
19
20
21
22
23
24


25
26
27
28
29
30
31

#include <time.h>

#import "OFDate.h"
#import "OFString.h"
#import "OFAutoreleasePool.h"



#import "of_strptime.h"

#import "TestsAppDelegate.h"

static OFString *module = @"OFDate";

@implementation TestsAppDelegate (OFDateTests)







>
>







18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

#include <time.h>

#import "OFDate.h"
#import "OFString.h"
#import "OFAutoreleasePool.h"

#import "OFInvalidFormatException.h"

#import "of_strptime.h"

#import "TestsAppDelegate.h"

static OFString *module = @"OFDate";

@implementation TestsAppDelegate (OFDateTests)
53
54
55
56
57
58
59





60
61
62
63
64
65
66
67





68
69
70
71
72
73
74
	    [[d2 description] isEqual: @"1970-01-02T01:00:05Z"])

	TEST(@"+[dateWithDateString:format:]",
	    [[[OFDate dateWithDateString: @"2000-06-20T12:34:56+0200"
				  format: @"%Y-%m-%dT%H:%M:%S%z"] description]
	    isEqual: @"2000-06-20T10:34:56Z"]);






	/*
	 * We can only test local dates that specify a time zone, as the local
	 * time zone differs between systems.
	 */
	TEST(@"+[dateWithLocalDateString:format:]",
	    [[[OFDate dateWithLocalDateString: @"2000-06-20T12:34:56-0200"
				       format: @"%Y-%m-%dT%H:%M:%S%z"]
	    description] isEqual: @"2000-06-20T14:34:56Z"]);






	TEST(@"-[isEqual:]",
	    [d1 isEqual: [OFDate dateWithTimeIntervalSince1970: 0]] &&
	    ![d1 isEqual: [OFDate dateWithTimeIntervalSince1970: 0.0000001]])

	TEST(@"-[compare:]", [d1 compare: d2] == OF_ORDERED_ASCENDING)








>
>
>
>
>








>
>
>
>
>







55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
	    [[d2 description] isEqual: @"1970-01-02T01:00:05Z"])

	TEST(@"+[dateWithDateString:format:]",
	    [[[OFDate dateWithDateString: @"2000-06-20T12:34:56+0200"
				  format: @"%Y-%m-%dT%H:%M:%S%z"] description]
	    isEqual: @"2000-06-20T10:34:56Z"]);

	EXPECT_EXCEPTION(@"Detection of unparsed in "
	    @"+[dateWithDateString:format:]", OFInvalidFormatException,
	    [OFDate dateWithDateString: @"2000-06-20T12:34:56+0200x"
				format: @"%Y-%m-%dT%H:%M:%S%z"])

	/*
	 * We can only test local dates that specify a time zone, as the local
	 * time zone differs between systems.
	 */
	TEST(@"+[dateWithLocalDateString:format:]",
	    [[[OFDate dateWithLocalDateString: @"2000-06-20T12:34:56-0200"
				       format: @"%Y-%m-%dT%H:%M:%S%z"]
	    description] isEqual: @"2000-06-20T14:34:56Z"]);

	EXPECT_EXCEPTION(@"Detection of unparsed in "
	    @"+[dateWithLocalDateString:format:]", OFInvalidFormatException,
	    [OFDate dateWithLocalDateString: @"2000-06-20T12:34:56+0200x"
				     format: @"%Y-%m-%dT%H:%M:%S%z"])

	TEST(@"-[isEqual:]",
	    [d1 isEqual: [OFDate dateWithTimeIntervalSince1970: 0]] &&
	    ![d1 isEqual: [OFDate dateWithTimeIntervalSince1970: 0.0000001]])

	TEST(@"-[compare:]", [d1 compare: d2] == OF_ORDERED_ASCENDING)