This commit only looks at the `Returns:` lines in the documentation, and
has examined all of them in the file. Function arguments have not been
checked.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Helps: #2227
This commit only looks at the `Returns:` lines in the documentation, and
has examined all of them in the file. Function arguments have not been
checked.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Helps: #2227
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>
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>
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>
This doesn’t change the behaviour of the code, but should squash some
compiler/static analysis warnings about ‘are you sure you got the
precedence right here?’.
Coverity CID: #1159470
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
The `nameprep()` function in `ghostutils.c` is quite complex, and does a
lot of allocations. This means it can take a long time on long hostnames
(on the order of 10KB long). Hostnames should never be that long,
though, so impose some loose length limits.
oss-fuzz#27371
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
It’s possible that GLib will eventually be compiled against a version of
libc which supports `close_range()` (hence `HAVE_CLOSE_RANGE` will be
defined), but then run against an older kernel which doesn’t support it.
In this case, we want to fall back to `fdwalk()`, which should work on
such systems.
This is what cpython does: 3529718925/Python/fileutils.c (L2227)
Spotted by Allison Karlitskaya in !1688.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
They extend the behavior of, respectively, -p and -s options of the
glib test framework
Currently test suite are only run for one level under -p path, for
example, testfilemonitor -p /monitor would execute the following tests:
/monitor/atomic-replace
/monitor/file-changes
/monitor/dir-monitor
/monitor/dir-not-existent
/monitor/cross-dir-moves
With the --run-prefix the sub-test suite file will be executed:
/monitor/atomic-replace
/monitor/file-changes
/monitor/dir-monitor
/monitor/dir-not-existent
/monitor/cross-dir-moves
/monitor/file/hard-links
The --skip-prefix and run-prefix seems symmetrical, but there is a
difference with skip towards run:
--skip-prefix will use a prefix while --run-prefix only work for a valid test path.
For example and for the following test family:
/monitor/atomic-replace
/monitor/file-changes
/monitor/dir-monitor
/monitor/dir-not-existent
/monitor/cross-dir-moves
/monitor/file/hard-links
while --run-prefix /mon will not execute anything, --skip-prefix /mon
will skip all of these tests.
See #2238 which references this change.
- Add a test for parsing FILE scheme from uri
It had taken from GST test_protocol_case
- Add a split uri test with encoded spaces in its path
It had taken from GST test_uri_get_location
- Add tests for g_uri_is_valid
It had taken from GST test_uri_misc
Note that the 4 followings uri failed under gst_uri_is_valid but not
under g_uri_is_valid
B:\\foo.txt
B:/foo.txt
B://foo.txt
B:foo.txt
- Add tests for g_uri_split
It had taken from GST test_url_parsing
- Add tests for test_uri_normalize and test_uri_parsing_relative
The test URI had been taken from GST test_url_normalization
- Add tests for test_uri_iter_params
It had taken from GST test_url_unescape_equals_in_http_query
Closes#2150
Signed-off-by: Frederic Martinsons <frederic.martinsons@sigfox.com>
It still works, and deprecating it would be quite disruptive (as it’s
used in headers), so amend the documentation to point people to
`G_NORETURN` instead.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Helps: #994
For URIs produced in string form, the path should be normalized and port
omitted when the default one is used. When querying the path and port of
a GUri (using getters or g_uri_split()) the normalized path and the
default port should be returned when they were omitted in the parsed URI.
Closes#2257
`g_time_zone_new_identifier()` returns NULL in the FreeBSD test setup,
presumably because `TZ` isn’t set.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Helps: #553
Use `g_time_zone_new_identifier()` instead so you can get error
checking.
Adapt the tests to match.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Helps: #553
In the Windows destructor list, consistently access
`g_private_destructors` using atomic primitives.
`g_atomic_pointer_compare_and_exchange()` should be equivalent to
`InterlockedCompareExchangePointer()`, but is a bit more understandable
in a general GLib context, and pairs with `g_atomic_pointer_get()`. (I
can’t find a Windows API equivalent for that.)
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Helps: #600
`volatile` should not be used to indicate atomic variables, and we
shouldn’t encourage its use. Keep the tests, since they check that we
don’t emit warnings when built against incorrect old code which uses
`volatile`. But add a comment to stop copy/paste use of `volatile`
in the future.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Helps: #600
This is technically an API break, but since the type is meant to be
opaque (third party code is not meant to treat it like an integer) it
should not cause problems.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Helps: #600
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
It’s not necessary and provides no thread safety guarantees.
The `volatile` qualifiers on the function arguments have to be kept, as
they are (unfortunately) part of the API.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Helps: #600
It’s not necessary and provides no thread safety guarantees.
The `volatile` qualifiers on the function arguments have to be kept, as
they are (unfortunately) part of the API.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Helps: #600
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
And drop the `volatile` qualifier from the variable, as that doesn’t
help with thread safety.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Helps: #600
And drop the `volatile` qualifier from the variable, as that doesn’t
help with thread safety.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Helps: #600
Add a new variant of `g_time_zone_new()` which returns `NULL` on
failure to load a timezone, rather than silently returning UTC.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Fixes: #553
In file included from glib/glib.h:86,
from glib/tests/uri.c:25:
glib/gtestutils.h:134:96: error: comparison of integer expressions of different signedness: ‘gint’ {aka ‘int’} and ‘GConvertError’
134 | if (!err || (err)->domain != dom || (err)->code != c) \
| ^~
glib/tests/uri.c:182:9: note: in expansion of macro ‘g_assert_error’
182 | g_assert_error (error, G_CONVERT_ERROR, file_to_uri_tests[i].expected_error);
| ^~~~~~~~~~~~~~
glib/gtestutils.h:134:96: error: comparison of integer expressions of different signedness: ‘gint’ {aka ‘int’} and ‘GConvertError’
134 | if (!err || (err)->domain != dom || (err)->code != c) \
| ^~
glib/tests/uri.c:220:9: note: in expansion of macro ‘g_assert_error’
220 | g_assert_error (error, G_CONVERT_ERROR, file_from_uri_tests[i].expected_error);
| ^~~~~~~~~~~~~~
glib/tests/uri.c: In function ‘test_uri_parsing_absolute’:
glib/gtestutils.h:134:96: error: comparison of integer expressions of different signedness: ‘gint’ {aka ‘int’} and ‘GUriError’
134 | if (!err || (err)->domain != dom || (err)->code != c) \
| ^~
glib/tests/uri.c:790:11: note: in expansion of macro ‘g_assert_error’
790 | g_assert_error (error, G_URI_ERROR, test->expected_error_code);
| ^~~~~~~~~~~~~~
In file included from glib/glibconfig.h:9,
from glib/gtypes.h:32,
from glib/galloca.h:32,
from glib/glib.h:30,
from glib/tests/uri.c:25:
glib/tests/uri.c: In function ‘test_uri_iter_params’:
glib/tests/uri.c:1495:51: error: comparison of integer expressions of different signedness: ‘gssize’ {aka ‘const long int’} and ‘long unsigned int’
1495 | params_tests[i].expected_n_params <= G_N_ELEMENTS (params_tests[i].expected_param_key_values) / 2);
| ^~
glib/gmacros.h:941:25: note: in definition of macro ‘G_LIKELY’
941 | #define G_LIKELY(expr) (expr)
| ^~~~
glib/tests/uri.c:1494:7: note: in expansion of macro ‘g_assert’
1494 | g_assert (params_tests[i].expected_n_params < 0 ||
| ^~~~~~~~
glib/tests/uri.c: In function ‘test_uri_parse_params’:
glib/tests/uri.c:1562:51: error: comparison of integer expressions of different signedness: ‘gssize’ {aka ‘const long int’} and ‘long unsigned int’
1562 | params_tests[i].expected_n_params <= G_N_ELEMENTS (params_tests[i].expected_param_key_values) / 2);
| ^~
glib/gmacros.h:941:25: note: in definition of macro ‘G_LIKELY’
941 | #define G_LIKELY(expr) (expr)
| ^~~~
glib/tests/uri.c:1561:7: note: in expansion of macro ‘g_assert’
1561 | g_assert (params_tests[i].expected_n_params < 0 ||
| ^~~~~~~~
glib/tests/uri.c: In function ‘run_file_to_uri_tests’:
glib/tests/uri.c:172:17: error: comparison of integer expressions of different signedness: ‘int’ and ‘long unsigned int’
172 | for (i = 0; i < G_N_ELEMENTS (file_to_uri_tests); i++)
| ^
glib/tests/uri.c: In function ‘run_file_from_uri_tests’:
glib/tests/uri.c:197:17: error: comparison of integer expressions of different signedness: ‘int’ and ‘long unsigned int’
197 | for (i = 0; i < G_N_ELEMENTS (file_from_uri_tests); i++)
| ^
glib/tests/uri.c: In function ‘run_file_roundtrip_tests’:
glib/tests/uri.c:276:17: error: comparison of integer expressions of different signedness: ‘int’ and ‘long unsigned int’
276 | for (i = 0; i < G_N_ELEMENTS (file_to_uri_tests); i++)
| ^
glib/tests/uri.c: In function ‘test_uri_parse_params’:
glib/tests/uri.c:1594:25: error: comparison of integer expressions of different signedness: ‘gsize’ {aka ‘long unsigned int’} and ‘gssize’ {aka ‘const long int’}
1594 | for (j = 0; j < params_tests[i].expected_n_params; j += 2)
| ^
glib/tests/timer.c: In function ‘test_timeval_from_iso8601’:
glib/tests/timer.c:220:17: error: comparison of integer expressions of different signedness: ‘gint’ {aka ‘int’} and ‘long unsigned int’
220 | for (i = 0; i < G_N_ELEMENTS (tests); i++)
| ^
glib/tests/timer.c: In function ‘test_timeval_to_iso8601’:
glib/tests/timer.c:260:17: error: comparison of integer expressions of different signedness: ‘gint’ {aka ‘int’} and ‘long unsigned int’
260 | for (i = 0; i < G_N_ELEMENTS (tests); i++)
| ^
This commit is the unmodified results of running
```
black $(git ls-files '*.py')
```
with black version 19.10b0. See #2046.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
glib/tests/shell.c: In function ‘main’:
glib/tests/shell.c:194:17: error: comparison of integer expressions of different signedness: ‘gint’ {aka ‘int’} and ‘long unsigned int’
194 | for (i = 0; i < G_N_ELEMENTS (cmdline_tests); i++)
| ^
glib/tests/shell.c:201:17: error: comparison of integer expressions of different signedness: ‘gint’ {aka ‘int’} and ‘long unsigned int’
201 | for (i = 0; i < G_N_ELEMENTS (quote_tests); i++)
| ^
glib/tests/shell.c:208:17: error: comparison of integer expressions of different signedness: ‘gint’ {aka ‘int’} and ‘long unsigned int’
208 | for (i = 0; i < G_N_ELEMENTS (unquote_tests); i++)
| ^
glib/tests/slice.c: In function ‘test_allocate’:
glib/tests/slice.c:146:17: error: comparison of integer expressions of different signedness: ‘gint’ {aka ‘int’} and ‘long unsigned int’
146 | for (i = 0; i < G_N_ELEMENTS(threads); i++)
| ^
glib/tests/slice.c:149:17: error: comparison of integer expressions of different signedness: ‘gint’ {aka ‘int’} and ‘long unsigned int’
149 | for (i = 0; i < G_N_ELEMENTS(threads); i++)
| ^
glib/tests/spawn-singlethread.c: In function ‘test_spawn_async_with_fds’:
glib/tests/spawn-singlethread.c:204:17: error: comparison of integer expressions of different signedness: ‘int’ and ‘long unsigned int’
204 | for (i = 0; i < G_N_ELEMENTS (tests); i++)
| ^
glib/guri.c: In function ‘should_normalize_empty_path’:
glib/guri.c:756:17: error: comparison of integer expressions of different signedness: ‘int’ and ‘long unsigned int’
756 | for (i = 0; i < G_N_ELEMENTS (schemes); ++i)
| ^
Since the loop variable changed signedness, it’s now possible for there
to be an infinite loop if `get_match_count()` returns an error. Guard
against that.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Coverity CID: #1436405
The macro wrapper to `g_assertion_message_cmpstrv()` makes sure that
neither array is `NULL`, so there’s no need for a second `NULL` check.
Additionally, this check happens after the arrays have already been
dereferenced, at which point the program would have crashed if the
arrays were `NULL`.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Coverity CID: #1436406, #1436407
We can’t do anything differently based on whether removing a file fails.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Coverity CID: #1354857
glib/tests/mainloop.c:55:1: error: missing initializer for field ‘closure_callback’ of ‘GSourceFuncs’ {aka ‘struct _GSourceFuncs’}
55 | };
| ^
In file included from glib/giochannel.h:33,
from glib/glib.h:54,
from glib/tests/mainloop.c:23:
glib/gmain.h:276:19: note: ‘closure_callback’ declared here
276 | GSourceFunc closure_callback;
| ^~~~~~~~~~~~~~~~
glib/tests/mainloop.c:422:1: error: missing initializer for field ‘closure_callback’ of ‘GSourceFuncs’ {aka ‘struct _GSourceFuncs’}
422 | };
| ^
In file included from glib/giochannel.h:33,
from glib/glib.h:54,
from glib/tests/mainloop.c:23:
glib/gmain.h:276:19: note: ‘closure_callback’ declared here
276 | GSourceFunc closure_callback;
| ^~~~~~~~~~~~~~~~
glib/tests/mainloop.c: In function ‘test_ready_time’:
glib/tests/mainloop.c:946:3: error: missing initializer for field ‘finalize’ of ‘GSourceFuncs’ {aka ‘struct _GSourceFuncs’}
946 | };
| ^
In file included from glib/giochannel.h:33,
from glib/glib.h:54,
from glib/tests/mainloop.c:23:
glib/gmain.h:272:14: note: ‘finalize’ declared here
272 | void (*finalize) (GSource *source); /* Can be NULL */
| ^~~~~~~~
glib/tests/mainloop.c: In function ‘test_unref_while_pending’:
glib/tests/mainloop.c:1088:3: error: missing initializer for field ‘closure_callback’ of ‘GSourceFuncs’ {aka ‘struct _GSourceFuncs’}
1088 | static GSourceFuncs funcs = { trivial_prepare, NULL, NULL, trivial_finalize };
| ^~~~~~
In file included from glib/giochannel.h:33,
from glib/glib.h:54,
from glib/tests/mainloop.c:23:
glib/gmain.h:276:19: note: ‘closure_callback’ declared here
276 | GSourceFunc closure_callback;
| ^~~~~~~~~~~~~~~~
In file included from glib/glibconfig.h:9,
from glib/gtypes.h:32,
from glib/galloca.h:32,
from glib/glib.h:30,
from glib/tests/mainloop.c:23:
glib/tests/mainloop.c: In function ‘test_source_unix_fd_api’:
glib/tests/mainloop.c:1403:3: error: missing initializer for field ‘finalize’ of ‘GSourceFuncs’ {aka ‘struct _GSourceFuncs’}
1403 | };
| ^
In file included from glib/giochannel.h:33,
from glib/glib.h:54,
from glib/tests/mainloop.c:23:
glib/gmain.h:272:14: note: ‘finalize’ declared here
272 | void (*finalize) (GSource *source); /* Can be NULL */
| ^~~~~~~~
glib/tests/mainloop.c: At top level:
glib/tests/mainloop.c:1843:1: error: missing initializer for field ‘closure_callback’ of ‘GSourceFuncs’ {aka ‘struct _GSourceFuncs’}
1843 | };
| ^
In file included from glib/giochannel.h:33,
from glib/glib.h:54,
from glib/tests/mainloop.c:23:
glib/gmain.h:276:19: note: ‘closure_callback’ declared here
276 | GSourceFunc closure_callback;
| ^~~~~~~~~~~~~~~~
glib/tests/mainloop.c:1919:1: error: missing initializer for field ‘closure_callback’ of ‘GSourceFuncs’ {aka ‘struct _GSourceFuncs’}
1919 | };
| ^
In file included from glib/giochannel.h:33,
from glib/glib.h:54,
from glib/tests/mainloop.c:23:
glib/gmain.h:276:19: note: ‘closure_callback’ declared here
276 | GSourceFunc closure_callback;
| ^~~~~~~~~~~~~~~~
glib/tests/mainloop.c:2002:1: error: missing initializer for field ‘closure_callback’ of ‘GSourceFuncs’ {aka ‘struct _GSourceFuncs’}
2002 | };
| ^
In file included from glib/giochannel.h:33,
from glib/glib.h:54,
from glib/tests/mainloop.c:23:
glib/gmain.h:276:19: note: ‘closure_callback’ declared here
276 | GSourceFunc closure_callback;
| ^~~~~~~~~~~~~~~~
glib/tests/option-context.c: In function ‘callback_test_optional_5’:
glib/tests/option-context.c:945:5: error: missing initializer for field ‘arg_description’ of ‘GOptionEntry’ {aka ‘struct _GOptionEntry’}
945 | { { "dummy", 'd', 0, G_OPTION_ARG_NONE, &dummy, NULL },
| ^
In file included from glib/glib.h:64,
from glib/tests/option-context.c:23:
glib/goption.h:268:16: note: ‘arg_description’ declared here
268 | const gchar *arg_description;
| ^~~~~~~~~~~~~~~
glib/tests/option-context.c: In function ‘callback_test_optional_6’:
glib/tests/option-context.c:983:5: error: missing initializer for field ‘arg_description’ of ‘GOptionEntry’ {aka ‘struct _GOptionEntry’}
983 | { { "dummy", 'd', 0, G_OPTION_ARG_NONE, &dummy, NULL },
| ^
In file included from glib/glib.h:64,
from glib/tests/option-context.c:23:
glib/goption.h:268:16: note: ‘arg_description’ declared here
268 | const gchar *arg_description;
| ^~~~~~~~~~~~~~~
glib/tests/option-context.c: In function ‘callback_test_optional_7’:
glib/tests/option-context.c:1021:5: error: missing initializer for field ‘arg_description’ of ‘GOptionEntry’ {aka ‘struct _GOptionEntry’}
1021 | { { "dummy", 'd', 0, G_OPTION_ARG_NONE, &dummy, NULL },
| ^
In file included from glib/glib.h:64,
from glib/tests/option-context.c:23:
glib/goption.h:268:16: note: ‘arg_description’ declared here
268 | const gchar *arg_description;
| ^~~~~~~~~~~~~~~
glib/tests/option-context.c: In function ‘callback_test_optional_8’:
glib/tests/option-context.c:1059:5: error: missing initializer for field ‘arg_description’ of ‘GOptionEntry’ {aka ‘struct _GOptionEntry’}
1059 | { { "dummy", 'd', 0, G_OPTION_ARG_NONE, &dummy, NULL },
| ^
In file included from glib/glib.h:64,
from glib/tests/option-context.c:23:
glib/goption.h:268:16: note: ‘arg_description’ declared here
268 | const gchar *arg_description;
| ^~~~~~~~~~~~~~~
glib/tests/option-context.c: In function ‘test_group_captions’:
glib/tests/option-context.c:123:21: error: comparison of integer expressions of different signedness: ‘gint’ {aka ‘int’} and ‘long unsigned int’
123 | for (j = 0; j < G_N_ELEMENTS (test_name_base); ++j)
| ^
glib/tests/option-context.c: In function ‘option_context_parse_command_line’:
glib/tests/option-context.c:2364:46: error: operand of ‘?:’ changes signedness from ‘int’ to ‘guint’ {aka ‘unsigned int’} due to unsignedness of other operand
2364 | return success ? argv_len - argv_new_len : -1;
| ^~
glib/gtestutils.h:134:96: error: comparison of integer expressions of different signedness: ‘gint’ {aka ‘int’} and ‘GMarkupError’
134 | if (!err || (err)->domain != dom || (err)->code != c) \
| ^~
glib/tests/markup-collect.c:168:7: note: in expansion of macro ‘g_assert_error’
168 | g_assert_error (error, G_MARKUP_ERROR, test->error_code);
| ^~~~~~~~~~~~~~
glib/tests/spawn-multithreaded.c: In function ‘multithreaded_test_run’:
glib/tests/spawn-multithreaded.c:41:17: error: comparison of integer expressions of different signedness: ‘int’ and ‘guint’ {aka ‘unsigned int’}
41 | for (i = 0; i < n_threads; i++)
| ^
glib/tests/spawn-multithreaded.c:49:17: error: comparison of integer expressions of different signedness: ‘int’ and ‘guint’ {aka ‘unsigned int’}
49 | for (i = 0; i < n_threads; i++)
| ^
glib/tests/tree.c: In function ‘test_tree_traverse’:
glib/tests/tree.c:394:17: error: comparison of integer expressions of different signedness: ‘gint’ {aka ‘int’} and ‘long unsigned int’
394 | for (i = 0; i < G_N_ELEMENTS (orders); i++)
| ^
glib/tests/markup-collect.c: In function ‘main’:
glib/tests/markup-collect.c:227:17: error: comparison of integer expressions of different signedness: ‘int’ and ‘long unsigned int’
227 | for (i = 0; i < G_N_ELEMENTS (tests); i++)
| ^
glib/tests/scannerapi.c: In function ‘test_scanner_tokens’:
glib/tests/scannerapi.c:124:17: error: comparison of integer expressions of different signedness: ‘guint’ {aka ‘unsigned int’} and ‘gint’ {aka ‘const int’}
124 | for (i = 1; i < tokbuflen; i++)
| ^
glib/tests/regex.c: In function ‘test_match_all’:
glib/tests/regex.c:1317:19: error: comparison of integer expressions of different signedness: ‘gint’ {aka ‘int’} and ‘guint’ {aka ‘unsigned int’}
1317 | if (match_count != g_slist_length (data->expected))
| ^~
glib/tests/rcbox.c: In function ‘test_rcbox_alignment’:
glib/tests/rcbox.c:246:17: error: comparison of integer expressions of different signedness: ‘int’ and ‘long unsigned int’
246 | for (i = 0; i < G_N_ELEMENTS (block_sizes); i++)
| ^
glib/tests/rcbox.c: In function ‘test_atomic_rcbox_alignment’:
glib/tests/rcbox.c:270:17: error: comparison of integer expressions of different signedness: ‘int’ and ‘long unsigned int’
270 | for (i = 0; i < G_N_ELEMENTS (block_sizes); i++)
| ^
glib/tests/protocol.c: In function ‘test_error’:
glib/tests/protocol.c:252:17: error: comparison of integer expressions of different signedness: ‘gint’ {aka ‘int’} and ‘long unsigned int’
252 | for (i = 0; i < G_N_ELEMENTS (tests); i++)
| ^
glib/tests/pattern.c: In function ‘main’:
glib/tests/pattern.c:218:17: error: comparison of integer expressions of different signedness: ‘gint’ {aka ‘int’} and ‘long unsigned int’
218 | for (i = 0; i < G_N_ELEMENTS (compile_tests); i++)
| ^
glib/tests/pattern.c:225:17: error: comparison of integer expressions of different signedness: ‘gint’ {aka ‘int’} and ‘long unsigned int’
225 | for (i = 0; i < G_N_ELEMENTS (match_tests); i++)
| ^
glib/tests/pattern.c:232:17: error: comparison of integer expressions of different signedness: ‘gint’ {aka ‘int’} and ‘long unsigned int’
232 | for (i = 0; i < G_N_ELEMENTS (equal_tests); i++)
| ^
glib/tests/gvariant.c: In function ‘append_tuple_type_string’:
glib/tests/gvariant.c:206:17: error: comparison of integer expressions of different signedness: ‘gsize’ {aka ‘long unsigned int’} and ‘gint’ {aka ‘int’}
206 | for (i = 0; i < size; i++)
| ^
glib/tests/gvariant.c:210:13: error: comparison of integer expressions of different signedness: ‘gsize’ {aka ‘long unsigned int’} and ‘int’
210 | if (i < size - 1)
| ^
glib/tests/gvariant.c:223:17: error: comparison of integer expressions of different signedness: ‘gsize’ {aka ‘long unsigned int’} and ‘gint’ {aka ‘int’}
223 | for (i = 0; i < size; i++)
| ^
glib/tests/gvariant.c: In function ‘describe_type’:
glib/tests/gvariant.c:386:29: error: comparison of integer expressions of different signedness: ‘gsize’ {aka ‘long unsigned int’} and ‘gint’ {aka ‘int’}
386 | for (i = 0; i < length; i++)
| ^
glib/tests/gvariant.c: In function ‘describe_info’:
glib/tests/gvariant.c:882:23: error: comparison of integer expressions of different signedness: ‘gsize’ {aka ‘long unsigned int’} and ‘gint’ {aka ‘int’}
882 | for (i = 0; i < length; i++)
| ^
glib/tests/gvariant.c: In function ‘check_offsets’:
glib/tests/gvariant.c:962:21: error: comparison of integer expressions of different signedness: ‘gsize’ {aka ‘long unsigned int’} and ‘gint’ {aka ‘int’}
962 | for (i = 0; i < length; i++)
| ^
glib/tests/gvariant.c: In function ‘tree_instance_check_gvariant’:
glib/tests/gvariant.c:2636:44: error: comparison of integer expressions of different signedness: ‘gboolean’ {aka ‘int’} and ‘guint64’ {aka ‘long unsigned int’}
2636 | return g_variant_get_boolean (value) == tree->data.integer;
| ^~
glib/tests/gvariant.c: In function ‘test_varargs’:
glib/tests/gvariant.c:3090:26: error: comparison of integer expressions of different signedness: ‘gint’ {aka ‘int’} and ‘guint’ {aka ‘unsigned int’}
3090 | g_assert_true (val == i++ || val == 0);
| ^~
glib/tests/once.c: In function ‘test_once_init_multi_threaded’:
glib/tests/once.c:183:17: error: comparison of integer expressions of different signedness: ‘gint’ {aka ‘int’} and ‘long unsigned int’
183 | for (i = 0; i < G_N_ELEMENTS (threads); i++)
| ^
glib/tests/once.c:186:17: error: comparison of integer expressions of different signedness: ‘gint’ {aka ‘int’} and ‘long unsigned int’
186 | for (i = 0; i < G_N_ELEMENTS (threads); i++)
| ^
glib/tests/markup-escape.c: In function ‘main’:
glib/tests/markup-escape.c:152:17: error: comparison of integer expressions of different signedness: ‘gint’ {aka ‘int’} and ‘long unsigned int’
152 | for (i = 0; i < G_N_ELEMENTS (escape_tests); i++)
| ^
../glib.git/glib/tests/markup-escape.c:159:17: error: comparison of integer expressions of different signedness: ‘gint’ {aka ‘int’} and ‘long unsigned int’
159 | for (i = 0; i < G_N_ELEMENTS (unichar_tests); i++)
| ^
glib/tests/node.c: In function ‘traversal_test’:
glib/tests/node.c:214:17: error: comparison of integer expressions of different signedness: ‘gint’ {aka ‘int’} and ‘long unsigned int’
214 | for (i = 0; i < G_N_ELEMENTS (orders); i++)
| ^
glib/tests/logging.c: In function ‘compare_fields’:
glib/tests/logging.c:403:17: error: comparison of integer expressions of different signedness: ‘int’ and ‘gsize’ {aka ‘long unsigned int’}
403 | for (i = 0; i < n1; i++)
| ^
glib/tests/logging.c:405:21: error: comparison of integer expressions of different signedness: ‘int’ and ‘gsize’ {aka ‘long unsigned int’}
405 | for (j = 0; j < n2; j++)
| ^
glib/tests/logging.c:410:13: error: comparison of integer expressions of different signedness: ‘int’ and ‘gsize’ {aka ‘long unsigned int’}
410 | if (j == n2)
| ^~
glib/tests/hash.c: In function ‘test_hash_misc’:
glib/tests/hash.c:616:43: error: comparison of integer expressions of different signedness: ‘gint’ {aka ‘int’} and ‘guint’ {aka ‘unsigned int’}
616 | if (values_len != keys_len && keys_len != g_hash_table_size (hash_table))
| ^~
glib/tests/tree.c: In function ‘test_tree_traverse’:
glib/tests/tree.c:394:17: error: comparison of integer expressions of different signedness: ‘gint’ {aka ‘int’} and ‘long unsigned int’
394 | for (i = 0; i < G_N_ELEMENTS (orders); i++)
| ^
This changes it so when a segment is encoded it will be
normalized at parse time which ensures its valid and
it can more easily be compared with other uris.
It’s technically undefined behaviour in C to copy between two
potentially-overlapping regions of memory (just like it is when calling
`memcpy()`). This can easily happen with union members; and the ones in
`GScanner` in particular.
Fix that by copying through an intermediate variable.
Coverity CID: #1427317, 1427340
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
This test asserts that g_file_set_contents_full() will fail when used
on a read-only file, but processes with CAP_DAC_OVERRIDE on Linux or
uid 0 on traditional Unix can and do ignore DAC permissions.
See also #2027, #2028.
Bug-Debian: https://bugs.debian.org/973271
Signed-off-by: Simon McVittie <smcv@collabora.com>
If there is a file descriptor source that has a lower priority
than the one for sources that are going to be dispatched,
all subsequent file descriptor sources (internally sorted by
file descriptor identifier) do not get an update in their GPollRec
and later on wrong sources can be dispatched.
Fix this by first finding the first GPollRec that matches the current
GPollFD, instead of relying on it to be the current one. At
the same time, document the assumptions about the ordering of the
file descriptor records and array and make explicit in the documentation
that the array needs to be passed to g_main_context_check() as it was
received from g_main_context_query().
Added a new test that reproduces the bug by creating two file
descriptor sources and an idle one. Since the first
file descriptor created has a lower identifier and a low priority,
the second one is not dispatched even when it has the same, higher,
priority as the idle source. After fixing this bug, both
higher priority sources are dispatched as expected.
While this patch was written independently, a similar fix for this
bug was first submitted by Eugene M in GNOME/glib!562. Having a
second fix that basically does the same is a reassurance that we
are in the right here.
Fixes#1592
This allows compilers to check the format placeholders properly. It
fixes compilation on clang, which gives a warning about untrusted
strings being passed on to subsequent functions which require format
placeholders.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Just like gcc, clang has supported `__typeof__` for a long time, so
allow it to be used. This fixes compilation of `gio/gcredentials.c` on
macOS (which uses clang by default).
I don’t know which version clang started supporting `__typeof__` in, so
there’s no version check. One can be added in future if there are
problems.
This fixes commit 5b2bee3f53.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
The addition causes the date to shift
forward into 1st of the next month, because a 0-based offset
is compared to be "more than" the days in the month instead of "more than
or equal to".
This is triggered by corner-cases where transition date is 6 days
off the end of the month and our calculations put it at N+1th day of the
month (where N is the number of days in the month). The subtraction should
be triggered to move the date back a week, putting it 6 days off the end;
for example, October 25 for CET DST transition; but due to incorrect comparison
the date isn't shifted back, we add 31 days to October 1st and end up
at November 1st).
Fixes issue #2215.
This reverts commit 851241f19a.
That commit avoids a performance regression but introduces a behavior regression:
changes to /etc/localtime have no effect for the remaining of the application's
runtime.
With the optimization introduced by the previous commit, we can pass NULL to
g_time_zone_new() repeatedly with no performance drawback, so we no longer have
to workaround this case.
Fixes: #2224
We cache GTimeZone instances to avoid expensive construction when the
same id is requested again.
However, if the NULL id is passed to g_time_zone_new(), we always
construct a new instance for the default/fallback timezone.
With the recent introduction of some heavy calculations[1], repeated
instance construction in such cases has visible performance impact in
nautilus list view and other such GtkTreeView consumers.
To avoid this, cache reference to a constructed default timezone and
use it the next time g_time_zone_new() is called with NULL argument,
as long as the default identifier doesn't change. We already did the
same for the local timezone[2].
Fixes: https://gitlab.gnome.org/GNOME/glib/-/issues/2204
Based on idea proposed by Sebastian Keller <skeller@gnome.org>.
[1] 25d950b61f
[2] 551e83662d
The win32 implementation of `g_getenv()` uses GSlice (from within
GQuark), which results in a deadlock when examining the `G_SLICE`
environment variable.
Fix that by inlining a basic implementation of `g_getenv()` at that call
site.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Fixes: #2225
There are various places glib uses __typeof__ for type safety, but
that's a GNUC extension. C++11 has standard decltype() that does a
similar job, at least for cases we care about.
This avoids C++ code to always have to cast return value of
g_object_ref() which was causing type kind of error:
error: invalid conversion from ‘gpointer’ {aka ‘void*’} to
‘GstElementFactory*’ {aka ‘_GstElementFactory*’} [-fpermissive]
g_has_typeof macro is wrongly in the public g_ namespace, internaly
symbols are usually in the glib_ namespace. This will also allow to
define glib_typeof differently on non-GNUC compilers (e.g. c++11
decltype).
glib/gtestutils.h:134:96: error: comparison of integer expressions of different signedness: ‘gint’ {aka ‘int’} and ‘GFileError’
134 | if (!err || (err)->domain != dom || (err)->code != c) \
| ^~
glib/tests/fileutils.c:1072:15: note: in expansion of macro ‘g_assert_error’
1072 | g_assert_error (error, G_FILE_ERROR, tests[i].expected_error);
| ^~~~~~~~~~~~~~
glib/tests/array-test.c: In function ‘array_remove_index’:
glib/tests/array-test.c:388:17: error: comparison of integer expressions of different signedness: ‘gint’ {aka ‘int’} and ‘guint’ {aka ‘unsigned int’}
388 | for (i = 0; i < garray->len; i++)
| ^
glib/tests/array-test.c: In function ‘array_remove_index_fast’:
glib/tests/array-test.c:425:17: error: comparison of integer expressions of different signedness: ‘gint’ {aka ‘int’} and ‘guint’ {aka ‘unsigned int’}
425 | for (i = 0; i < garray->len; i++)
| ^
glib/tests/array-test.c: In function ‘array_remove_range’:
glib/tests/array-test.c:462:17: error: comparison of integer expressions of different signedness: ‘gint’ {aka ‘int’} and ‘guint’ {aka ‘unsigned int’}
462 | for (i = 0; i < garray->len; i++)
| ^
glib/tests/array-test.c: In function ‘array_sort’:
glib/tests/array-test.c:604:17: error: comparison of integer expressions of different signedness: ‘gint’ {aka ‘int’} and ‘guint’ {aka ‘unsigned int’}
604 | for (i = 0; i < garray->len; i++)
| ^
glib/tests/array-test.c: In function ‘array_sort_with_data’:
glib/tests/array-test.c:636:17: error: comparison of integer expressions of different signedness: ‘gint’ {aka ‘int’} and ‘guint’ {aka ‘unsigned int’}
636 | for (i = 0; i < garray->len; i++)
| ^
glib/tests/array-test.c: In function ‘byte_array_sort’:
glib/tests/array-test.c:1876:17: error: comparison of integer expressions of different signedness: ‘gint’ {aka ‘int’} and ‘guint’ {aka ‘unsigned int’}
1876 | for (i = 0; i < gbarray->len; i++)
| ^
glib/tests/array-test.c: In function ‘byte_array_sort_with_data’:
glib/tests/array-test.c:1904:17: error: comparison of integer expressions of different signedness: ‘gint’ {aka ‘int’} and ‘guint’ {aka ‘unsigned int’}
1904 | for (i = 0; i < gbarray->len; i++)
| ^
These slightly improve the tests but, more importantly, squash a
scan-build warning about assigning to a variable which is never
subsequently used:
```
../../../glib/tests/keyfile.c:1150:3: warning: Value stored to 'value' is never read
value = g_key_file_get_string (keyfile, "a", "key=", &error);
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../../../glib/tests/keyfile.c:1159:3: warning: Value stored to 'value' is never read
value = g_key_file_get_string (keyfile, "a", "key[", &error);
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../../../glib/tests/keyfile.c:1176:3: warning: Value stored to 'value' is never read
value = g_key_file_get_string (keyfile, "a", " key", &error);
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3 warnings generated.
```
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
This should silence the following warning:
```
../../../glib/tests/mutex.c:206:5: warning: 1st function call argument is an uninitialized value
g_thread_join (threads[i]);
^~~~~~~~~~~~~~~~~~~~~~~~~~
```
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
This should avoid the warning:
```
../../../glib/tests/mainloop.c:119:3: warning: Value stored to 'id' is never read
id = g_source_attach (source, ctx);
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
```
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
This introduces no functional changes, but should squash a warning from
`scan-build`:
```
../../../glib/ghash.c:575:3: warning: Value stored to 'small' is never read
small = FALSE;
```
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
GLib uses NULL-terminated string arrays (GStrv) in a number of places, however
these are quite hard to construct in C when the number of elements is not known
in advance. GStrvBuilder wraps GPtrArray to make these easy to create with
type safety and does the memory management for you.
When unref'ing child sources, the lock is already held. But instead of
passing TRUE to g_source_unref_internal it currently passes whether the
lock was already held outside of the current invocation. Just pass TRUE
to fix this possible issue.
It’s landed in kernel 5.9: http://lkml.iu.edu/hypermail/linux/kernel/2008.0/02649.html
Note, this is untested because I currently don’t have kernel 5.9. We can
fix anything up if it breaks once the new syscall is wrapped in glibc.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
This allows programs that want to change how log messages are printed,
such as gnome-terminal (gnome-terminal#42) and Flatpak, to override
the log-writer or the legacy log-handler without having to reimplement
the G_MESSAGES_DEBUG filtering logic.
Signed-off-by: Simon McVittie <smcv@collabora.com>
GLib code normally prints info and debug messages to stdout,
but that interferes with programs that are documented to produce
machine-readable output such as JSON or XML on stdout. In particular,
if such a program uses a GLib-based library, setting G_MESSAGES_DEBUG
will typically result in that library's debug messages going to the
program's stdout and corrupting the machine-readable output.
Unix programs can avoid this by using dup2() to move the original stdout
to another fd, then dup2() again to make the new stdout a copy of stderr,
but it's easier if we provide a way to not write debug messages to
stdout in the first place. Calling
g_log_writer_default_set_use_stderr (TRUE) results in behaviour
resembling Python's logging.basicConfig(), with all diagnostics going
to stderr.
Suggested by Allison Karlitskaya on glib#2087.
Signed-off-by: Simon McVittie <smcv@collabora.com>
The basic API that this commit adds allows in-order iterating over a GTree.
For this the following API were implemented or exported:
1) Returning the first or the last node in the tree,
2) Taking a pointer to a node in the tree and returning the previous or the
next in-order node,
3) Allowing to do a binary search for a particular key value and returning
the pointer to its node,
4) Returning the newly inserted or set node from both insert and replace
functions, so this node is immediately available and does not have to be
looked up,
5) Traversing the tree in-order providing a node pointer to the
caller-provided traversal function.
Most of the above functions were already present in the code, but they
returned the value that is stored at a particular node instead of the
pointer to the node itself.
So most of the code for these new API calls is shared with these existing
ones, just adapted to return the pointer to the node.
Additionally, the so called "lower bound" and "upper bound" operations
were implemented.
The first one returns the first element that is greater than or equal to
the searched key, while the second returns the first element that is
strictly greater than the searched key.
Signed-off-by: Maciej S. Szmigiero <maciej.szmigiero@oracle.com>
* Add a debug assert checking whether we have really removed all nodes in
g_tree_remove_all(),
* Print a "LEFT" and "RIGHT" headers before printing a particular tree
branch in g_tree_node_dump(),
* Make the whole thing actually buildable again in the debug mode by
conditionally providing g_tree_dump() declaration in glib/gtree.h.
Signed-off-by: Maciej S. Szmigiero <maciej.szmigiero@oracle.com>
The return value from `g_utf8_get_char_validated()` is a `gunichar`,
which is unsigned, so comparing it with `> 0` is always going to return
true, even for return values `(gunichar) -1` and `(gunichar) -2`, which
indicate errors.
Handle them more explicitly.
oss-fuzz#26083
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
This is very unlikely to happen, but add error handling to mirror the
other calls to `safe_open()`, and shut Coverity up.
Coverity CID: #1430611
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
If this fails to compile on some particularly bizarre Unix platform,
we can relax these assertions; but our expectation is that gssize is
POSIX ssize_t, and that on Unix, GPid is POSIX pid_t.
Signed-off-by: Simon McVittie <smcv@collabora.com>
This is a step towards glib#1484. We officially require a C99 toolchain,
so we can statically assert that our artisanal hand-crafted integer
types are compatible with the ones we would like to recommend people
use instead.
If there are *still* platforms where <stdint.h> is problematic, these
static assertions can act as an early-warning that future GLib releases
will make a C99-compliant <stdint.h> a hard requirement, in ways that
are less straightforward to avoid (see glib#1484 and glib!1300).
Signed-off-by: Simon McVittie <smcv@collabora.com>
We have been passing a &resolved_identifier address around for multiple
functions to set it. Each function may either:
1. leaving it for the next function to set, if returning early;
2. set it to a duplicate of the passed identifier, if not NULL;
3. get a fallback value and set it, otherwise.
This can be simplified by setting it early to either:
1. a duplicate of the passed identifier, if not NULL;
2. a fallback value, otherwise.
This way we can avoid some unnecessary string duplication and freeing.
Also, on Windows, we avoid calling windows_default_tzname() twice.
But the main motivation for this change is enabling the performance
optimization in the next commit.
When the TZ environment variable is not set, we get the local timezone
identifier by reading specific files.
We are going to need these identifiers earlier, so split this logic into
its own function, in preparation for the next commit.
Based on idea proposed by Sebastian Keller <skeller@gnome.org>.
This is exactly the test case from oss-fuzz which triggers a negative
overflow when constructing dates.
oss-fuzz#22758
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
This bumps the coverage of `parse_host()` and `parse_ip_literal()` up to
100% of lines and branches.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
The previous parsing code could read off the end of a URI if it had an
incorrect %-escaped character in.
Fix that, and more closely implement parsing for the syntax defined in
RFC 6874, which is the amendment to RFC 3986 which specifies zone ID
syntax.
This requires reworking some network-address tests, which were
previously treating zone IDs incorrectly.
oss-fuzz#23816
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Having the goto labels at the bottom of a function makes things a little
more readable. This introduces no functional changes.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
This introduces no functional changes, but makes the memory ownership a
little clearer and reduces the length of the code.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
This introduces no functional changes, but will make future changes to
the code a little cleaner.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
If the old value is destroyed before updating the TLS value in pthreads
(or the Windows equivalent) then there’s a risk of infinite recursion if
`g_private_replace()` is called from within the `GDestroyNotify`.
Avoid that by destroying the old value after doing the TLS update.
Thanks to Matthias Clasen for diagnosing the issue.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Fixes: #2210
Rather than invalidating the cache by comparing `TZ` to the cached
timezone identifier, key entirely off the value of `TZ` (and a cached
copy of it).
This fixes the timezone cache being constantly invalidated if `TZ` is
`NULL` (which will always differ from the identifier of the default
local timezone which is constructed from `g_time_zone_new (NULL)`.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Fixes: #2204
They shouldn’t be used to free a list from part-way through, as that
is confusing and will leave a dangling pointer from the previous list
element.
Spotted by Gary Kramlich in !1653.
Signed-off-by: Philip Withnall <pwithnall@endlessos.org>
Symbols on x86 are prefixed with an underscore
but symbols on x64/ARM/ARM64 are not.
Relevant information concerning the prefixes for the architectures
can be found in the vcpkg project [1,2], where arm and arm64 builds
are part of the CI.
Specifically, _WIN64 is defined on Windows ARM64, so this issue is
only visible when building on ARM32.
[1] 08e74979df/ports/glib/fix-arm-builds.patch
[2] https://github.com/microsoft/vcpkg/pull/6116
glib/tests/date.c:778:17: error: comparison of integer expressions of
different signedness: ‘gint’ {aka ‘int’} and ‘long unsigned int’
778 | for (i = 0; i < G_N_ELEMENTS (check_years); i++)
| ^
glib/tests/collate.c:300:17: error: comparison of integer expressions
of different signedness: ‘gint’ {aka ‘int’} and ‘long unsigned int’
300 | for (i = 0; i < G_N_ELEMENTS (test); i++)
| ^
`uri` is always non-`NULL` by the time the `fail` label is reached, so
drop the `NULL` pointer check. Inline the `fail` code since it’s only
used from two places.
Coverity CID: #1430970
Signed-off-by: Philip Withnall <withnall@endlessm.com>
If one thread pool thread fails to set its scheduler settings, it’s
likely that all the rest of them will fail for the same reason. Avoid
printing duplicate critical warnings in that case.
Signed-off-by: Philip Withnall <withnall@endlessm.com>
Fixes: #2191