Skip to content

Commit fd1492e

Browse files
authored
Merge pull request libgit2#4408 from hkleynhans/pos_neg_zero_offset_sig
signature: distinguish +0000 and -0000 UTC offsets
2 parents 8c928be + f063daf commit fd1492e

File tree

3 files changed

+35
-2
lines changed

3 files changed

+35
-2
lines changed

include/git2/types.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ typedef struct git_packbuilder git_packbuilder;
159159
typedef struct git_time {
160160
git_time_t time; /**< time in seconds from epoch */
161161
int offset; /**< timezone offset, in minutes */
162+
char sign; /**< indicator for questionable '-0000' offsets in signature */
162163
} git_time;
163164

164165
/** An action signature (e.g. for committers, taggers, etc) */

src/signature.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ int git_signature_new(git_signature **sig_out, const char *name, const char *ema
9090

9191
p->when.time = time;
9292
p->when.offset = offset;
93+
p->when.sign = (offset < 0) ? '-' : '+';
9394

9495
*sig_out = p;
9596
return 0;
@@ -113,6 +114,7 @@ int git_signature_dup(git_signature **dest, const git_signature *source)
113114

114115
signature->when.time = source->when.time;
115116
signature->when.offset = source->when.offset;
117+
signature->when.sign = source->when.sign;
116118

117119
*dest = signature;
118120

@@ -137,6 +139,7 @@ int git_signature__pdup(git_signature **dest, const git_signature *source, git_p
137139

138140
signature->when.time = source->when.time;
139141
signature->when.offset = source->when.offset;
142+
signature->when.sign = source->when.sign;
140143

141144
*dest = signature;
142145

@@ -257,6 +260,7 @@ int git_signature__parse(git_signature *sig, const char **buffer_out,
257260
*/
258261
if (hours <= 14 && mins <= 59) {
259262
sig->when.offset = (hours * 60) + mins;
263+
sig->when.sign = tz_start[0];
260264
if (tz_start[0] == '-')
261265
sig->when.offset = -sig->when.offset;
262266
}
@@ -299,7 +303,7 @@ void git_signature__writebuf(git_buf *buf, const char *header, const git_signatu
299303
assert(buf && sig);
300304

301305
offset = sig->when.offset;
302-
sign = (sig->when.offset < 0) ? '-' : '+';
306+
sign = (sig->when.offset < 0 || sig->when.sign == '-') ? '-' : '+';
303307

304308
if (offset < 0)
305309
offset = -offset;
@@ -320,6 +324,7 @@ bool git_signature__equal(const git_signature *one, const git_signature *two)
320324
git__strcmp(one->name, two->name) == 0 &&
321325
git__strcmp(one->email, two->email) == 0 &&
322326
one->when.time == two->when.time &&
323-
one->when.offset == two->when.offset;
327+
one->when.offset == two->when.offset &&
328+
one->when.sign == two->when.sign;
324329
}
325330

tests/commit/signature.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "clar_libgit2.h"
2+
#include "signature.h"
23

34
static int try_build_signature(const char *name, const char *email, git_time_t time, int offset)
45
{
@@ -99,3 +100,29 @@ void test_commit_signature__from_buf(void)
99100
git_signature_free(sign);
100101
}
101102

103+
void test_commit_signature__from_buf_with_neg_zero_offset(void)
104+
{
105+
git_signature *sign;
106+
107+
cl_git_pass(git_signature_from_buffer(&sign, "Test User <test@test.tt> 1461698487 -0000"));
108+
cl_assert_equal_s("Test User", sign->name);
109+
cl_assert_equal_s("test@test.tt", sign->email);
110+
cl_assert_equal_i(1461698487, sign->when.time);
111+
cl_assert_equal_i(0, sign->when.offset);
112+
cl_assert_equal_i('-', sign->when.sign);
113+
git_signature_free(sign);
114+
}
115+
116+
void test_commit_signature__pos_and_neg_zero_offsets_dont_match(void)
117+
{
118+
git_signature *with_neg_zero;
119+
git_signature *with_pos_zero;
120+
121+
cl_git_pass(git_signature_from_buffer(&with_neg_zero, "Test User <test@test.tt> 1461698487 -0000"));
122+
cl_git_pass(git_signature_from_buffer(&with_pos_zero, "Test User <test@test.tt> 1461698487 +0000"));
123+
124+
cl_assert(!git_signature__equal(with_neg_zero, with_pos_zero));
125+
126+
git_signature_free((git_signature *)with_neg_zero);
127+
git_signature_free((git_signature *)with_pos_zero);
128+
}

0 commit comments

Comments
 (0)