192 Commits

Author SHA1 Message Date
Philip Withnall
0ffdbebd9a
gdatetime: Factor out an undersized variable
For long input strings, it would have been possible for `i` to overflow.
Avoid that problem by using the `tz_length` instead, so that we count up
rather than down.

This commit introduces no functional changes (outside of changing
undefined behaviour), and can be verified using the identity
`i === length - tz_length`.

Signed-off-by: Philip Withnall <pwithnall@gnome.org>
2025-02-18 17:31:48 +00:00
Philip Withnall
3672764a17
gdatetime: Factor out some string pointer arithmetic
Makes the following code a little clearer, but doesn’t introduce any
functional changes.

Signed-off-by: Philip Withnall <pwithnall@gnome.org>
2025-02-18 17:31:14 +00:00
Philip Withnall
0b225e7cd8
gdatetime: Track timezone length as an unsigned size_t
It’s guaranteed to be in (0, length] by the calculations above.

This avoids the possibility of integer overflow through `gssize` not
being as big as `size_t`.

Signed-off-by: Philip Withnall <pwithnall@gnome.org>
2025-02-18 17:00:51 +00:00
Philip Withnall
2fa1e18361
gdatetime: Fix potential integer overflow in timezone offset handling
This one is much harder to trigger than the one in the previous commit,
but mixing `gssize` and `gsize` always runs the risk of the former
overflowing for very (very very) long input strings.

Avoid that possibility by not using the sign of the `tz_offset` to
indicate its validity, and instead using the return value of the
function.

Signed-off-by: Philip Withnall <pwithnall@gnome.org>
2025-02-18 16:51:36 +00:00
Philip Withnall
8d60d7dc16
gdatetime: Fix integer overflow when parsing very long ISO8601 inputs
This will only happen with invalid (or maliciously invalid) potential
ISO8601 strings, but `g_date_time_new_from_iso8601()` needs to be robust
against that.

Prevent `length` overflowing by correctly defining it as a `size_t`.
Similarly for `date_length`, but additionally track its validity in a
boolean rather than as its sign.

Spotted by chamalsl as #YWH-PGM9867-43.

Signed-off-by: Philip Withnall <pwithnall@gnome.org>
2025-02-18 16:44:58 +00:00
Michael Catanzaro
a893d622c0 gdatetime: fix double free in format parser
If %#Z is followed by %Z then we accidentally free the tmp variable from
the previous iteration of the loop a second time. Good job to the static
analysis tool (probably Coverity) that found this.

Fortunately it's unlikely that a realistic application would do this.

I've also added a new test that crashes without the fix
2024-09-18 01:48:36 +01:00
Philip Withnall
7a7d8d548a Merge branch 'wfloat-conversion' into 'main'
build: Enable -Wfloat-conversion and fix warnings

See merge request GNOME/glib!4126
2024-09-17 17:57:11 +00:00
Luke T. Shumaker
e4a2aa8f39 docs: Wrap things that gi-docgen mistakes as HTML tags in backticks
This are nasty, because they mean words get dropped from the
documentation.  This can be seen at

 - https://docs.gtk.org/gio/ctor.DBusNodeInfo.new_for_xml.html where
   it reads "one top-level element" instead of "one top-level <node>
   element".

 - https://docs.gtk.org/gio/method.ProxyResolver.lookup.html where it
   reads "where could be" instead of "where <protocol> could be".

 - https://docs.gtk.org/gio/method.Socket.get_option.html where it
   reads "[][gio-gnetworking.h]" instead of
   "[<gio/gnetworking.h>][gio-gnetworking.h" (also, this markdown link
   needs fixed, but let's save that for another commit).

 - https://docs.gtk.org/glib/ctor.DateTime.new_from_iso8601.html where
   the text is incomprehensible; "strings of the form are supported"
   instead of "strings of the form <date><sep><time><tz> are
   supported"; further references to <sep>, <date>, <time>, and <tz>
   are similarly mangled.

 - https://docs.gtk.org/glib/method.MatchInfo.fetch_named.html and
   https://docs.gtk.org/glib/method.MatchInfo.fetch_named_pos.html
   where the regex reads as "(?Pa)?b" instead of as "(?P<X>a)?b",
   changing the meaning of it.

 - https://docs.gtk.org/glib/method.Regex.match_all_full.html is all
   wack because the "<a>" in the example string is taken to be an HTML
   link; and all example strings and regexes are mangled (also, one of
   the regexes has a stray ";" in it, but let's save that for another
   commit).

 - https://docs.gtk.org/glib/method.Regex.replace.html where it simply
   reads "\g" instead of "\g<number>" and "\g<name>".

Fix those.
2024-08-13 15:19:21 -06:00
Philip Withnall
f24bb8dc19
gutilsprivate: Factor out g_isnan() helper
There are a couple of places in the code which use `isnan()` and have
platform-specific workarounds for it. Unify those, and extend the
workaround to work for msys2-mingw32.

It seems that msys2-mingw32 can’t automatically use `isnan()` in a wider
mode than `float`:
```
In file included from ../glib/gdatetime.c:60:
../glib/gdatetime.c: In function 'g_date_time_new':
../glib/gdatetime.c:1648:14: error: conversion from 'gdouble' {aka 'double'} to 'float' may change value [-Werror=float-conversion]
 1648 |       isnan (seconds) ||
      |              ^~~~~~~
cc1.exe: all warnings being treated as errors
```

See: https://gitlab.gnome.org/pwithnall/glib/-/jobs/4022715

Using it in float mode on all platforms should not change behaviour, as
a conversion from `(double) NAN` to `float` should still give `NAN`.

Signed-off-by: Philip Withnall <pwithnall@gnome.org>

Helps: #3405
2024-07-07 17:53:19 +01:00
Philip Withnall
2713255574
glib: Add explicit casts for some double → other numeric type conversions
If we enable `-Wfloat-conversion`, these warn about a possible loss of
precision due to an implicit conversion from `double` to some other
numeric type.

The warning is correct: there is a possible loss of precision here. In
these instances, we don’t care, as the floating point arithmetic is
being done to do some imprecise scaling or imprecise timing. A loss of
precision is not a problem.

So, add an explicit cast to squash the warning.

Signed-off-by: Philip Withnall <pwithnall@gnome.org>

Helps: #3405
2024-06-28 14:24:55 +01:00
Philip Withnall
e12e81a02d
gdatetime: Fix string type used to initialise array
This fixes commit 057f0fcbfba3b7c4e4b8730154bad9e5118a3ef8. I didn’t
notice that `tmp` is an array of strings, not an array of chars, and
somehow my compiler didn’t warn. Seems only the macOS CI job is spotting
the problem here.

Signed-off-by: Philip Withnall <pwithnall@gnome.org>
2024-04-26 10:28:47 +01:00
Philip Withnall
057f0fcbfb
gdatetime: Fix a maybe-uninitialized warning
scan-build thinks that `tmp` can be dereferenced before it’s all been
assigned to. I don’t think that’s the case, because the number of
elements in it which have been assigned to is tracked as `i`. But static
analysers find that kind of state tracking hard to reason about, so
let’s just zero-initialise the array to simplify things.

Signed-off-by: Philip Withnall <pwithnall@gnome.org>

Helps: #1767
2024-04-25 23:58:04 +01:00
Philip Withnall
362f92b693
glib: Fix various implicit conversions from size_t to smaller types
Basically various trivial instances of the following MSVC compiler
warning:
```
../gio/gio-tool-set.c(50): warning C4267: '=': conversion from 'size_t' to 'int', possible loss of data
```

Signed-off-by: Philip Withnall <pwithnall@gnome.org>
2024-04-25 12:39:33 +01:00
Simon McVittie
6de98cc255 gdatetime: Ignore %E modifier on 64-bit big-endian for the moment
This doesn't appear to work reliably on s390x and ppc64, returning
the results that were expected without %E or intermittently crashing.
It seems that on little-endian 64-bit, the intptr_t returned by the
undocumented _NL_TIME_ERA_NUM_ENTRIES correctly has the number of entries
in its low-order half (at the time of writing, 0x0000'0000'0000'000b for
Japan), but on big-endian 64-bit, it has the number of entries in its
high-order half instead (for example 0x0000'000b'0000'0000 for Japan),
with the low-order half being all-zero or possibly uninitialized.

Making this reliable will require some sort of defined API from glibc.

Helps: https://gitlab.gnome.org/GNOME/glib/-/issues/3225
Bug-Debian: https://bugs.debian.org/1060735
Signed-off-by: Simon McVittie <smcv@collabora.com>
2024-01-15 14:18:40 +00:00
Philip Withnall
994bf21d9d gdatetime: Fix title of documentation comment
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
2023-12-22 14:48:30 +00:00
Xavier Claessens
a4edf1e3ae GDateTime: Add usec precision API for unix time 2023-12-20 07:48:10 -05:00
Philip Withnall
8ee00cbad8 gdatetime: Disable ERA support on platforms which don’t support this
So far, that’s BSD: it supports `nl_langinfo()`, but not `ERA`.

Signed-off-by: Philip Withnall <pwithnall@gnome.org>

Helps: #3119
2023-11-28 23:56:22 +00:00
Philip Withnall
c8e3302007 gdatetime: Fix copyright/author information on recent GDateTime changes
I wrote the changes before clarifying the copyright status of my
contract with the GNOME Foundation, and forgot to update them.

Signed-off-by: Philip Withnall <pwithnall@gnome.org>

Helps: #3119
2023-11-28 23:13:27 +00:00
Philip Withnall
09fe2aa78d gdatetime: Fix a minor leak on changing locale
Signed-off-by: Philip Withnall <philip@tecnocode.co.uk>
2023-11-28 19:32:03 +00:00
Philip Withnall
df4aea7620 gdatetime: Add support for %E modifier to g_date_time_format()
The `%E` modifier causes dates to be formatted using an alternative era
representation for years. This doesn’t do anything for most dates, but
in locales such as Thai and Japanese it causes years to be printed using
era names.

In Thai, this means the Thai solar calendar
(https://en.wikipedia.org/wiki/Thai_solar_calendar). In Japanese, this
means Japanese era names
(https://en.wikipedia.org/wiki/Japanese_era_name).

The `%E` modifier syntax follows what’s supported in glibc — see
nl_langinfo(3).

Supporting this is quite involved, as it means loading the `ERA`
description from libc and parsing it.

Unit tests are included.

Signed-off-by: Philip Withnall <philip@tecnocode.co.uk>

Fixes: #3119
2023-11-28 19:32:02 +00:00
Philip Withnall
afd8dde13f gdatetime: Fix incorrect alt-digits being used after changing locale
The alt-digits are loaded from `nl_langinfo()` in a `GOnce` section,
which means `nl_langinfo()` is not re-queried after the process changes
locale (if that happens).

So, change the `GOnce` to a mutex and store the locale of the alt-digits
alongside them. This will introduce contention when calling
`format_number()` is called, but how often are multiple threads trying
to format dates at the same time?

If this does get highlighted as a performance problem, the other
approach I considered was a `GPrivate` struct containing all the
locale-specific cached data. That comes at the cost of using a
`GPrivate` slot (although that’s only particularly expensive on Windows,
and the locale code is quite different for Windows, so perhaps that
could be avoided entirely). It does mean that all locale printing could
be lock-free and still safely update cached data on a locale change.

Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
2023-10-22 22:10:07 +01:00
Philip Withnall
b1ae8fb85f gdatetime: Fix minor leaks from strup/strdown calls
These were accidentally introduced in commit 0b114b2687.

Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
2023-10-18 15:54:33 +01:00
Matthias Clasen
7b4d00e0a4 docs: Move GDateTime SECTION
Move the contents to the struct comment.

Helps: #3037
2023-10-11 17:38:30 +01:00
Rick Calixte
0b114b2687 Add support for case modifiers to DateTime 2023-10-03 08:43:03 +00:00
Philip Withnall
ca98d60d6d gdatetime: Improve Markdown formatting of g_date_time_format() docs
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>

Fixes: #2969
2023-04-05 17:53:41 +01:00
Peter Bloomfield
574a2ecfa9 gdatetime: add NULL guard in g_date_time_new_now()
Add a missing g_return_() check in g_date_time_new_now().
A clear warning is better than a NULL pointer dereference.
2022-10-09 19:39:58 -04:00
Aleksander Morgado
737ca7de91 gdatetime: add missing g_return_() check in g_date_time_format_iso8601
A clear warning is better than a NULL pointer dereference.

Signed-off-by: Aleksander Morgado <aleksandermj@chromium.org>
2022-10-04 21:37:58 +00:00
Philip Withnall
41691cc4c8 Merge branch 'more-spdx' into 'main'
Add more SPDX license headers

See merge request GNOME/glib!2706
2022-07-05 11:06:49 +00:00
Maksym Hazevych
7169f6e1e5 gdatetime: Use figure space for %e
Helps: #2655
2022-06-20 14:46:23 +01:00
Maksym Hazevych
7074122f30 gdatetime: Pad numbers with numeric space
Padding numbers with a typical space character doesn't align them well
because it has a different size. Instead, we need to use the "U+2007"
figure (numeric) space that has the same size as a numerical digit.
This is only visible when using the `tnum` font feature that
makes numbers monospace.

Closes #2655
2022-06-20 14:28:09 +01:00
Philip Withnall
26409f19cd Add SPDX license headers for LGPL-2.1-or-later to various files
These have all been added manually, as I’ve finished all the files which
I can automatically detect.

All the license headers in this commit are for LGPL-2.1-or-later, and
all have been double-checked against the license paragraph in the file
header.

Signed-off-by: Philip Withnall <pwithnall@endlessos.org>

Helps: #1415
2022-06-01 12:44:23 +01:00
Philip Withnall
1d6c46a0ac gdatetime: Rework array indexing to satisfy scan-build
This introduces no functional changes, but reworks the array indexing so
that scan-build has a better idea about the array bounds. This squashes
the scan-build warning:
```
../../../../source/glib/glib/gdatetime.c:2292:20: warning: The left operand of '>=' is a garbage value [core.UndefinedBinaryOperatorResult]
      if (days [i] >= day_of_year)
          ~~~~~~~~ ^
```

Signed-off-by: Philip Withnall <pwithnall@endlessos.org>

Helps: #1767
2022-04-28 11:22:53 +01:00
Carlos Garnacho
c3cc6bf5eb glib: Format GDateTime ISO8601 years as %C%y
The current use of %Y does not take into account that %Y will
not pad the year with 0's, meanwhile ISO8601 does expect a full
YYYY format for all dates. This breaks the formatting with dates
prior to the year 1000.

Split this into %C%y so 2-digit, 0-padded century and year are
printed separately, this gives the expected YYYY format.
2022-03-21 12:56:42 +00:00
Loic Le Page
d5580edfa7 Fix non-initialized variable in glib/gdatetime.c 2022-02-18 10:59:30 +01:00
Emmanuel Fleury
33c2968669 Fix always false statement warning in glib/gdatetime.c
glib/gdatetime.c:896:27: warning: comparison is always false due to limited range of data type
   if ((gint64) tv->tv_sec > G_MAXINT64 - 1 ||
                           ^
2021-10-12 18:03:58 +02:00
Frederic Martinsons
782eb1f7af Add private functions to correctly convert datetime when LC_TIME is not UTF8
Functions (_g_get_time_charset and _g_get_ctype_charset) to get LC_TIME and LC_CTYPE charset
by using nl_langinfo with _NL_TIME_CODESET and CODESET).
Another functions (_g_locale_time_to_utf8 and _g_locale_ctype_to_utf8) which uses thel and format
the input string accordingly.
Add new test cases with mixing UTF8 and non UTF8 LC_TIME along with UTF8
and non UTF8 LC_MESSAGES.

Closed #2055

Signed-off-by: Frederic Martinsons <frederic.martinsons@sigfox.com>
2021-03-27 09:28:10 +01:00
Frederic Martinsons
c4df3b23c4 Reorganize headers inclusion alphabetically
Signed-off-by: Frederic Martinsons <frederic.martinsons@sigfox.com>
2021-03-27 08:29:08 +01:00
Chun-wei Fan
a2454d731a gdatetime.c: Fix MSVC builds for lack of NAN items
Use a fallback for isnan() on Visual Studio 2012 or earlier, and define
NAN if it does not exist.
2021-01-04 15:38:27 +00:00
Philip Withnall
50a3d0bf9d gdatetime: Use isnan() instead of !isfinite()
Both are provided by libm, but `isnan()` is provided as a macro, whereas
`isfinite()` is an actual function, and hence libm has to be available
at runtime. That didn’t trivially work on FreeBSD, resulting in this
refactor.

`isfinite(x)` is equivalent to `!isnan(x) && !isinfinite(x)`. The case
of `x` being (negative or positive) infinity is already handled by the
range checks on the next line, so it’s safe to switch to `isnan()` here.

Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
2020-12-11 15:39:47 +00:00
Philip Withnall
5d7f4b8f04 gdatetime: Remove floating point from seconds parsing code
Rather than parsing the seconds in an ISO 8601 date/time using a pair of
floating point numbers (numerator and denominator), use two integers
instead. This avoids issues around floating point precision, and also
makes it easier to check for potential overflow from overlong inputs.

This last point means that the `isfinite()` check can be removed, as it
was covering the case where a NAN was generated, which isn’t now
possible using integer arithmetic.

Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
2020-12-11 15:36:56 +00:00
Philip Withnall
c3805d74ba gdatetime: Disallow NAN as a number of seconds in a GDateTime
The fiendish thing about NAN is that it never compares TRUE against
anything, so the limit checks `seconds < 0.0 || seconds >= 60.0` were
never triggering.

oss-fuzz#28473

Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
2020-12-09 14:50:02 +00:00
Jean Felder
cd6b35f7d2 gdatetime: Fix g_date_time_equal annotation
The parameters C type need to be overriden to GDateTime.
2020-11-24 09:45:58 +00:00
Jean Felder
b513b358a8 gdatetime: Fix g_date_time_hash annotation
The parameter C type needs to be overriden to GDateTime.
2020-11-24 09:45:58 +00:00
Jean Felder
7ec3c26e67 gdatetime: Fix g_date_time_compare annotation
The parameters C type need to be overriden to GDateTime.
2020-11-24 09:45:58 +00:00
Sebastian Dröge
72360eb8bd Merge branch '553-tz-errors' into 'master'
gtimezone: Add new constructor which can report errors

Closes #553

See merge request GNOME/glib!1760
2020-11-22 08:35:33 +00:00
Philip Withnall
1314ff93fc glib: Drop unnecessary volatile qualifiers from internal variables
These variables were already (correctly) accessed atomically. The
`volatile` qualifier doesn’t help with that.

Signed-off-by: Philip Withnall <pwithnall@endlessos.org>

Helps: #600
2020-11-20 14:40:19 +00:00
Philip Withnall
f9d0135a90 gdatetime: Port to use new g_time_zone_new_identifier() constructor
This allows slightly more reliable error checking on this code path.

Signed-off-by: Philip Withnall <pwithnall@endlessos.org>

Helps: #553
2020-11-18 11:31:57 +00:00
Philip Withnall
b5656d2524 gdatetime: Avoid integer overflow creating dates too far in the past
oss-fuzz#22758

Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
2020-10-01 11:46:15 +01:00
Philip Withnall
b0be67cc3f gdatetime: Widen a variable before multiplication
Otherwise it could possibly overflow on 32-bit machines if `year` is
high enough, although I don’t think that’s possible because of limits
applied on it by callers. This should shut Coverity up though.

The limits applied by callers could be circumvented by calling (say)
`g_date_time_add_years()` multiple times. That’s a bug, but not one I’m
going to fix today.

Coverity CID: #1159479
Signed-off-by: Philip Withnall <withnall@endlessm.com>
2020-08-18 10:23:43 +01:00
Johan Bjäreholt
8e13683f70 gdatetime: Format iso8601 strings with microsecond precision 2020-08-12 15:07:40 +02:00