@@ -38,7 +38,7 @@ void git_person__free(git_person *person)
3838 free (person );
3939}
4040
41- git_person * git_person__new (const char * name , const char * email , time_t time )
41+ git_person * git_person__new (const char * name , const char * email , time_t time , int offset )
4242{
4343 git_person * p ;
4444
@@ -48,6 +48,7 @@ git_person *git_person__new(const char *name, const char *email, time_t time)
4848 p -> name = git__strdup (name );
4949 p -> email = git__strdup (email );
5050 p -> time = time ;
51+ p -> timezone_offset = offset ;
5152
5253 if (p -> name == NULL || p -> email == NULL )
5354 goto cleanup ;
@@ -74,6 +75,51 @@ time_t git_person_time(git_person *person)
7475 return person -> time ;
7576}
7677
78+ int git_person_timezone_offset (git_person * person )
79+ {
80+ return person -> timezone_offset ;
81+ }
82+
83+ int git_person__parse_timezone_offset (const char * buffer , int * offset_out )
84+ {
85+ int offset , dec_offset ;
86+ int mins , hours ;
87+
88+ const char * offset_start ;
89+ char * offset_end ;
90+
91+ offset_start = buffer + 1 ;
92+
93+ if (offset_start [0 ] != '-' && offset_start [0 ] != '+' )
94+ return GIT_EOBJCORRUPTED ;
95+
96+ dec_offset = strtol (offset_start + 1 , & offset_end , 10 );
97+
98+ if (offset_end - offset_start != 5 )
99+ return GIT_EOBJCORRUPTED ;
100+
101+ hours = dec_offset / 100 ;
102+ mins = dec_offset % 100 ;
103+
104+ if (hours > 14 ) // see http://www.worldtimezone.com/faq.html
105+ return GIT_EOBJCORRUPTED ;
106+
107+ if (mins > 59 )
108+ return GIT_EOBJCORRUPTED ;
109+
110+ offset = (hours * 60 ) + mins ;
111+
112+ if (offset_start [0 ] == '-' )
113+ {
114+ offset *= -1 ;
115+ }
116+
117+ * offset_out = offset ;
118+
119+ return GIT_SUCCESS ;
120+ }
121+
122+
77123int git_person__parse (git_person * person , char * * buffer_out ,
78124 const char * buffer_end , const char * header )
79125{
@@ -82,6 +128,7 @@ int git_person__parse(git_person *person, char **buffer_out,
82128 int name_length , email_length ;
83129 char * buffer = * buffer_out ;
84130 char * line_end , * name_end , * email_end ;
131+ int offset = 0 ;
85132
86133 memset (person , 0x0 , sizeof (git_person ));
87134
@@ -128,13 +175,30 @@ int git_person__parse(git_person *person, char **buffer_out,
128175 if (person -> time == 0 )
129176 return GIT_EOBJCORRUPTED ;
130177
178+ if (git_person__parse_timezone_offset (buffer , & offset ) < GIT_SUCCESS )
179+ return GIT_EOBJCORRUPTED ;
180+
181+ person -> timezone_offset = offset ;
182+
131183 * buffer_out = (line_end + 1 );
132184 return GIT_SUCCESS ;
133185}
134186
135187int git_person__write (git_odb_source * src , const char * header , const git_person * person )
136188{
137- return git__source_printf (src , "%s %s <%s> %u\n" , header , person -> name , person -> email , person -> time );
189+ char * sign ;
190+ int offset , hours , mins ;
191+
192+ offset = person -> timezone_offset ;
193+ sign = (person -> timezone_offset < 0 ) ? "-" : "+" ;
194+
195+ if (offset < 0 )
196+ offset = - offset ;
197+
198+ hours = offset / 60 ;
199+ mins = offset % 60 ;
200+
201+ return git__source_printf (src , "%s %s <%s> %u %s%02d%02d\n" , header , person -> name , person -> email , person -> time , sign , hours , mins );
138202}
139203
140204
0 commit comments