Skip to content

Commit

Permalink
Fixed epoch date decoding being affected by the local time zone (#218)
Browse files Browse the repository at this point in the history
Fixes #209.
  • Loading branch information
agronholm committed Feb 21, 2024
1 parent 33f732c commit 6fb8469
Show file tree
Hide file tree
Showing 7 changed files with 18 additions and 6 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ jobs:
CFLAGS: "-UNDEBUG"
- name: Test with pytest
run: coverage run -m pytest -v
env:
TZ: America/New_York
- name: Generate coverage report
run: coverage xml
- name: Upload Coverage
Expand Down
1 change: 1 addition & 0 deletions docs/versionhistory.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ This library adheres to `Semantic Versioning <http://semver.org/>`_.
string that contained only ASCII characters
- Changed the return type annotations of ``cbor2.load()`` and ``cbor2.load()`` to return ``Any``
instead of ``object`` so as not to force users to make type casts
- Fixed decoding of epoch-based dates being affected by the local time zone in the C extension

**5.6.1** (2024-02-01)

Expand Down
2 changes: 2 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ minversion = 4.0.0
commands = python -m pytest {posargs}
package = editable
extras = test
setenv =
TZ=America/New_York
[testenv:docs]
extras = doc
Expand Down
10 changes: 5 additions & 5 deletions source/decoder.c
Original file line number Diff line number Diff line change
Expand Up @@ -1338,15 +1338,15 @@ static PyObject *
CBORDecoder_decode_epoch_date(CBORDecoderObject *self)
{
// semantic type 100
PyObject *num, *tuple, *ret = NULL;
PyObject *num, *ordinal, *ret = NULL;

num = decode(self, DECODE_NORMAL);
if (num) {
if (PyNumber_Check(num)) {
tuple = PyTuple_Pack(1, PyNumber_Multiply(num, PyLong_FromLong(24 * 60 * 60)));
if (tuple) {
ret = PyDate_FromTimestamp(tuple);
Py_DECREF(tuple);
ordinal = PyNumber_Add(num, _CBOR2_date_ordinal_offset);
if (ordinal) {
ret = PyObject_CallMethodObjArgs(PyDateTime_Date, _CBOR2_str_fromordinal, ordinal, NULL);
Py_DECREF(ordinal);
}
} else {
PyErr_Format(
Expand Down
2 changes: 1 addition & 1 deletion source/encoder.c
Original file line number Diff line number Diff line change
Expand Up @@ -1056,7 +1056,7 @@ CBOREncoder_encode_date(CBOREncoderObject *self, PyObject *value)
tmp = PyObject_CallMethodObjArgs(
value, _CBOR2_str_toordinal, NULL);
if (tmp && fp_write(self, "\xD8\x64", 2) == 0) {
ret = CBOREncoder_encode_int(self, PyNumber_Subtract(tmp, PyLong_FromLong(719163)));
ret = CBOREncoder_encode_int(self, PyNumber_Subtract(tmp, _CBOR2_date_ordinal_offset));
}
} else {
tmp = PyObject_CallMethodObjArgs(
Expand Down
6 changes: 6 additions & 0 deletions source/module.c
Original file line number Diff line number Diff line change
Expand Up @@ -621,6 +621,7 @@ _CBOR2_init_thread_locals(void)

PyObject *_CBOR2_empty_bytes = NULL;
PyObject *_CBOR2_empty_str = NULL;
PyObject *_CBOR2_date_ordinal_offset = NULL;
PyObject *_CBOR2_str_as_string = NULL;
PyObject *_CBOR2_str_as_tuple = NULL;
PyObject *_CBOR2_str_bit_length = NULL;
Expand All @@ -638,6 +639,7 @@ PyObject *_CBOR2_str_encode_date = NULL;
PyObject *_CBOR2_str_Fraction = NULL;
PyObject *_CBOR2_str_fromtimestamp = NULL;
PyObject *_CBOR2_str_FrozenDict = NULL;
PyObject *_CBOR2_str_fromordinal = NULL;
PyObject *_CBOR2_str_getvalue = NULL;
PyObject *_CBOR2_str_groups = NULL;
PyObject *_CBOR2_str_ip_address = NULL;
Expand Down Expand Up @@ -971,6 +973,7 @@ PyInit__cbor2(void)
INTERN_STRING(Fraction);
INTERN_STRING(fromtimestamp);
INTERN_STRING(FrozenDict);
INTERN_STRING(fromordinal);
INTERN_STRING(getvalue);
INTERN_STRING(groups);
INTERN_STRING(ip_address);
Expand Down Expand Up @@ -1000,6 +1003,9 @@ PyInit__cbor2(void)

#undef INTERN_STRING

if (!_CBOR2_date_ordinal_offset &&
!(_CBOR2_date_ordinal_offset = PyLong_FromLong(719163)))
goto error;
if (!_CBOR2_str_utc_suffix &&
!(_CBOR2_str_utc_suffix = PyUnicode_InternFromString("+00:00")))
goto error;
Expand Down
1 change: 1 addition & 0 deletions source/module.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ extern PyObject *_CBOR2_str_encode_date;
extern PyObject *_CBOR2_str_Fraction;
extern PyObject *_CBOR2_str_fromtimestamp;
extern PyObject *_CBOR2_str_FrozenDict;
extern PyObject *_CBOR2_str_fromordinal;
extern PyObject *_CBOR2_str_getvalue;
extern PyObject *_CBOR2_str_groups;
extern PyObject *_CBOR2_str_ip_address;
Expand Down

0 comments on commit 6fb8469

Please sign in to comment.