+Overview of changes in GLib 2.70.1
+==================================
+
+* Fix network changes not being signalled from NetworkManager (work by
+ Julian Andres Klode) (#2505)
+
+* Fix build when building with --fatal-meson-warnings (work by Eli Schwartz) (!2304)
+
+* Bugs fixed:
+ - #2505 g_network_monitor_nm never updates on connection change (listens for signal on wrong dbus interface)
+ - !2245 gdesktopappinfo: Do not call xterm when it does not exist, inform the caller the launch failed
+ - !2253 Backport !2251 “GString: Bump minimum size” to glib-2-70
+ - !2256 Backport !2254 “Small optimization for g_object_set” to glib-2-70
+ - !2259 Backport !2257 “Fix documentation for g_dbus_object_manager_get_object().” to glib-2-70
+ - !2262 Backport !2244 “gutils: Avoid segfault in g_get_user_database_entry” to glib-2-70
+ - !2271 Backport !2266 “fix uninitial variable” to glib-2-70
+ - !2276 Backport !2274 “Do not try to access errno after calling getpwnam_r.” to glib-2-70
+ - !2300 Backport !2285 “fix issues found by svace static code analyzer” to glib-2-70
+ - !2301 Backport !2293 “glib-private: Fix MSVC build with AddressSanitizer” to glib-2-70
+ - !2302 Backport !2291 “gnetworkmonitornm: Stop using removed PropertiesChanged signal” to glib-2-70
+ - !2304 meson: fix warnings for extract_all_objects function
+
+
Overview of changes in GLib 2.70.0
==================================
error))
{
*out_id = 0;
- *out_cookie = 0;
g_free (*out_cookie);
+ *out_cookie = 0;
ret = FALSE;
goto out;
}
* @manager: A #GDBusObjectManager.
* @object_path: Object path to look up.
*
- * Gets the #GDBusObjectProxy at @object_path, if any.
+ * Gets the #GDBusObject at @object_path, if any.
*
* Returns: (transfer full) (nullable): A #GDBusObject or %NULL. Free with
* g_object_unref().
if (check == NULL)
check = g_find_program_in_path ("dtterm");
if (check == NULL)
+ check = g_find_program_in_path ("xterm");
+ if (check == NULL)
{
- check = g_strdup ("xterm");
- g_debug ("Couldn’t find a terminal: falling back to xterm");
+ g_debug ("Couldn’t find a known terminal");
+ g_free (term_argv);
+ return FALSE;
}
term_argv[0] = check;
term_argv[1] = g_strdup ("-e");
* trying to rename across a filesystem boundary, which doesn't work. So
* we use g_stat here instead of g_lstat, to know where the symlink
* points to. */
- g_stat (path, &file_stat);
+ if (g_stat (path, &file_stat))
+ {
+ errsv = errno;
+ g_free (path);
+
+ g_set_io_error (error,
+ _("Error trashing file %s: %s"),
+ file, errsv);
+ return FALSE;
+ }
g_free (path);
}
{
if (lazy_stat (filename, &statbuf, &got_stat) == 0)
{
- times[0].tv_sec = statbuf.st_mtime;
+ times[0].tv_sec = statbuf.st_atime;
#if defined (HAVE_STRUCT_STAT_ST_ATIMENSEC)
times[0].tv_usec = statbuf.st_atimensec / 1000;
#elif defined (HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC)
gpointer arg0;
va_list args_copy;
+ g_return_if_fail (return_value != NULL);
+
G_VA_COPY (args_copy, args);
arg0 = (gpointer) va_arg (args_copy, gpointer);
if ((param_types[0] & G_SIGNAL_TYPE_STATIC_SCOPE) == 0 && arg0 != NULL)
arg0 = g_strdup (arg0);
va_end (args_copy);
- g_return_if_fail (return_value != NULL);
-
if (G_CCLOSURE_SWAP_DATA (closure))
{
data1 = closure->data;
}
static void
-update_cached_property (GDBusProxy *proxy,
- const char *property_name,
- GVariantDict *dict)
+proxy_properties_changed_cb (GDBusProxy *proxy,
+ GVariant *changed_properties,
+ GStrv invalidated_properties,
+ GNetworkMonitorNM *nm)
{
- GVariant *v;
-
- v = g_variant_dict_lookup_value (dict, property_name, NULL);
- if (!v)
- return;
- g_dbus_proxy_set_cached_property (proxy, property_name, v);
- g_variant_unref (v);
-}
-
-static void
-proxy_signal_cb (GDBusProxy *proxy,
- const gchar *sender_name,
- const gchar *signal_name,
- GVariant *parameters,
- GNetworkMonitorNM *nm)
-{
- GVariant *asv;
- GVariantDict *dict;
-
- if (g_strcmp0 (signal_name, "PropertiesChanged") != 0)
- return;
-
- g_variant_get (parameters, "(@a{sv})", &asv);
- if (!asv)
- return;
-
- dict = g_variant_dict_new (asv);
- g_variant_unref (asv);
- if (!dict)
- {
- g_warning ("Failed to handle PropertiesChanged signal from NetworkManager");
- return;
- }
-
- update_cached_property (nm->priv->proxy, "Connectivity", dict);
-
- g_variant_dict_unref (dict);
-
sync_properties (nm, TRUE);
}
return FALSE;
}
- nm->priv->signal_id = g_signal_connect (G_OBJECT (proxy), "g-signal",
- G_CALLBACK (proxy_signal_cb), nm);
+ nm->priv->signal_id = g_signal_connect (G_OBJECT (proxy), "g-properties-changed",
+ G_CALLBACK (proxy_properties_changed_cb), nm);
nm->priv->proxy = proxy;
sync_properties (nm, FALSE);
errsv = errno;
if (fd == -1)
{
+ g_free (path);
+ g_variant_builder_clear (&opt_builder);
g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errsv),
"Failed to open '%s'", path);
return FALSE;
}
dest_protocol = g_uri_parse_scheme (priv->dest_uri);
- g_return_val_if_fail (G_IS_INET_SOCKET_ADDRESS (priv->proxy_address),
- NULL);
+ if (!G_IS_INET_SOCKET_ADDRESS (priv->proxy_address))
+ {
+ g_free (dest_hostname);
+ g_free (dest_protocol);
+ }
+ g_return_val_if_fail (G_IS_INET_SOCKET_ADDRESS (priv->proxy_address), NULL);
inetsaddr = G_INET_SOCKET_ADDRESS (priv->proxy_address);
inetaddr = g_inet_socket_address_get_address (inetsaddr);
}
dest_protocol = g_uri_parse_scheme (priv->dest_uri);
+ if (!G_IS_INET_SOCKET_ADDRESS (priv->proxy_address))
+ {
+ g_free (dest_hostname);
+ g_free (dest_protocol);
+ }
g_return_if_fail (G_IS_INET_SOCKET_ADDRESS (priv->proxy_address));
inetsaddr = G_INET_SOCKET_ADDRESS (priv->proxy_address);
l = g_variant_get_int32 (variant);
else if (g_variant_type_equal (type, G_VARIANT_TYPE_INT64))
l = g_variant_get_int64 (variant);
+ else if (g_variant_type_equal (type, G_VARIANT_TYPE_HANDLE))
+ l = g_variant_get_handle (variant);
else
return FALSE;
u = g_variant_get_uint32 (variant);
else if (g_variant_type_equal (type, G_VARIANT_TYPE_UINT64))
u = g_variant_get_uint64 (variant);
- else if (g_variant_type_equal (type, G_VARIANT_TYPE_HANDLE))
- u = g_variant_get_handle (variant);
else
return FALSE;
else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_INT16) ||
g_variant_is_of_type (variant, G_VARIANT_TYPE_INT32) ||
- g_variant_is_of_type (variant, G_VARIANT_TYPE_INT64))
+ g_variant_is_of_type (variant, G_VARIANT_TYPE_INT64) ||
+ g_variant_is_of_type (variant, G_VARIANT_TYPE_HANDLE))
return g_settings_get_mapping_int (value, variant);
else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_DOUBLE))
else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_UINT16) ||
g_variant_is_of_type (variant, G_VARIANT_TYPE_UINT32) ||
- g_variant_is_of_type (variant, G_VARIANT_TYPE_UINT64) ||
- g_variant_is_of_type (variant, G_VARIANT_TYPE_HANDLE))
+ g_variant_is_of_type (variant, G_VARIANT_TYPE_UINT64))
return g_settings_get_mapping_unsigned_int (value, variant);
else if (g_variant_is_of_type (variant, G_VARIANT_TYPE_STRING) ||
(flags & FD_CLOEXEC) == 0)
{
flags |= FD_CLOEXEC;
- fcntl (fd, F_SETFD, flags);
+ (void) fcntl (fd, F_SETFD, flags);
}
}
#else
*
* The parser only requires 4 bytes.
*/
-#define SOCKS5_CONN_REP_LEN 255
+#define SOCKS5_CONN_REP_LEN 257
static gboolean
parse_connect_reply (const guint8 *data, gint *atype, GError **error)
{
guint8 data[SOCKS5_CONN_REP_LEN];
gint atype;
- if (!g_input_stream_read_all (in, data, 4, NULL,
+ if (!g_input_stream_read_all (in, data, 4 /* VER, REP, RSV, ATYP */, NULL,
cancellable, error))
goto error;
switch (atype)
{
case SOCKS5_ATYP_IPV4:
- if (!g_input_stream_read_all (in, data, 6, NULL,
- cancellable, error))
+ if (!g_input_stream_read_all (in, data,
+ 4 /* IPv4 length */ + 2 /* port */,
+ NULL, cancellable, error))
goto error;
break;
case SOCKS5_ATYP_IPV6:
- if (!g_input_stream_read_all (in, data, 18, NULL,
- cancellable, error))
+ if (!g_input_stream_read_all (in, data,
+ 16 /* IPv6 length */ + 2 /* port */,
+ NULL, cancellable, error))
goto error;
break;
case SOCKS5_ATYP_DOMAINNAME:
- if (!g_input_stream_read_all (in, data, 1, NULL,
- cancellable, error))
+ if (!g_input_stream_read_all (in, data, 1 /* domain name length */,
+ NULL, cancellable, error))
goto error;
- if (!g_input_stream_read_all (in, data, data[0] + 2, NULL,
- cancellable, error))
+ if (!g_input_stream_read_all (in, data,
+ data[0] /* domain name length */ + 2 /* port */,
+ NULL, cancellable, error))
goto error;
break;
}
subdir('xdgmime')
internal_deps += [xdgmime_lib]
- internal_objects += [xdgmime_lib.extract_all_objects()]
+ internal_objects += [xdgmime_lib.extract_all_objects(recursive: false)]
install_headers(gio_unix_include_headers, subdir : 'gio-unix-2.0/gio')
if glib_conf.has('HAVE_SYS_INOTIFY_H') and have_func_inotify_init1
subdir('inotify')
internal_deps += [ inotify_lib ]
- internal_objects += [inotify_lib.extract_all_objects()]
+ internal_objects += [inotify_lib.extract_all_objects(recursive: false)]
endif
# kevent
if have_func_kqueue and have_func_kevent
subdir('kqueue')
internal_deps += [ kqueue_lib ]
- internal_objects += [kqueue_lib.extract_all_objects()]
+ internal_objects += [kqueue_lib.extract_all_objects(recursive: false)]
endif
if host_system == 'windows'
subdir('win32')
internal_deps += [ giowin32_lib ]
- internal_objects += [giowin32_lib.extract_all_objects()]
+ internal_objects += [giowin32_lib.extract_all_objects(recursive: false)]
endif
if have_bash
XdgMimeMagicMatchlet *matchlet;
matchlet = malloc (sizeof (XdgMimeMagicMatchlet));
+ if (matchlet == NULL)
+ return NULL;
matchlet->indent = 0;
matchlet->offset = 0;
return XDG_MIME_MAGIC_ERROR;
matchlet = _xdg_mime_magic_matchlet_new ();
+
+ /* OOM */
+ if (matchlet == NULL)
+ return XDG_MIME_MAGIC_ERROR;
+
matchlet->indent = indent;
matchlet->offset = _xdg_mime_magic_read_a_number (magic_file, &end_of_file);
if (end_of_file)
{
case XDG_MIME_MAGIC_SECTION:
match = _xdg_mime_magic_match_new ();
+
+ /* OOM */
+ if (match == NULL)
+ return;
+
state = _xdg_mime_magic_parse_header (magic_file, match);
if (state == XDG_MIME_MAGIC_EOF || state == XDG_MIME_MAGIC_ERROR)
_xdg_mime_magic_match_free (match);
/* Save stderr for printing failure below */
int old_err = dup (2);
if (old_err != -1)
- fcntl (old_err, F_SETFD, fcntl (old_err, F_GETFD) | FD_CLOEXEC);
+ {
+ int getfd = fcntl (old_err, F_GETFD);
+ if (getfd != -1)
+ (void) fcntl (old_err, F_SETFD, getfd | FD_CLOEXEC);
+ }
close (0); dup (in_fd[0]); /* set the stdin to the in pipe */
close (1); dup (out_fd[1]); /* set the stdout to the out pipe */
if (translated_value)
break;
-
- g_free (translated_value);
- translated_value = NULL;
}
/* Fallback to untranslated key
#include "gstdioprivate.h"
/* gcc defines __SANITIZE_ADDRESS__, clang sets the address_sanitizer
- * feature flag */
-#if defined(__SANITIZE_ADDRESS__) || g_macro__has_feature(address_sanitizer)
+ * feature flag.
+ *
+ * MSVC defines __SANITIZE_ADDRESS__ as well when AddressSanitizer
+ * is enabled but __lsan_ignore_object() equivalent method is not supported
+ * See also
+ * https://docs.microsoft.com/en-us/cpp/sanitizers/asan-building?view=msvc-160
+ */
+#if !defined(_MSC_VER) && (defined(__SANITIZE_ADDRESS__) || g_macro__has_feature(address_sanitizer))
/*
* %_GLIB_ADDRESS_SANITIZER:
} *buffer = NULL;
gsize string_buffer_size = 0;
GError *local_error = NULL;
- int errsv = 0;
g_return_val_if_fail (user_name != NULL, NULL);
g_return_val_if_fail (error == NULL || *error == NULL, NULL);
*/
buffer = g_malloc0 (sizeof (*buffer) + string_buffer_size + 6);
- errno = 0;
retval = getpwnam_r (user_name, &buffer->pwd, buffer->string_buffer,
string_buffer_size, &passwd_file_entry);
- errsv = errno;
/* Bail out if: the lookup was successful, or if the user id can't be
* found (should be pretty rare case actually), or if the buffer should be
break;
}
else if (retval == 0 ||
- errsv == ENOENT || errsv == ESRCH ||
- errsv == EBADF || errsv == EPERM)
+ retval == ENOENT || retval == ESRCH ||
+ retval == EBADF || retval == EPERM)
{
/* Username not found. */
- g_unix_set_error_from_errno (&local_error, errsv);
+ g_unix_set_error_from_errno (&local_error, retval);
break;
}
- else if (errsv == ERANGE)
+ else if (retval == ERANGE)
{
/* Can’t allocate enough string buffer space. */
if (string_buffer_size > 32 * 1024)
{
- g_unix_set_error_from_errno (&local_error, errsv);
+ g_unix_set_error_from_errno (&local_error, retval);
break;
}
}
else
{
- g_unix_set_error_from_errno (&local_error, errsv);
+ g_unix_set_error_from_errno (&local_error, retval);
break;
}
}
{
g_clear_pointer (&buffer, g_free);
g_propagate_error (error, g_steal_pointer (&local_error));
- errno = errsv;
}
return (struct passwd *) g_steal_pointer (&buffer);
now = g_get_real_time ();
now_secs = (time_t) (now / 1000000);
now_tm = localtime (&now_secs);
- strftime (time_buf, sizeof (time_buf), "%H:%M:%S", now_tm);
+ if (G_LIKELY (now_tm != NULL))
+ strftime (time_buf, sizeof (time_buf), "%H:%M:%S", now_tm);
+ else
+ strcpy (time_buf, "(error)");
g_string_append_printf (gstring, "%s%s.%03d%s: ",
use_color ? "\033[34m" : "",
allocator_aligned_page_size (Allocator *allocator,
gsize n_bytes)
{
- gsize val = 1 << g_bit_storage (n_bytes - 1);
+ gsize val = (gsize) 1 << g_bit_storage (n_bytes - 1);
val = MAX (val, allocator->min_page_size);
return val;
}
{
DWORD error_code;
DWORD returned_bytes = 0;
- BYTE *data;
+ BYTE *data = NULL;
gsize to_copy;
/* This is 16k. It's impossible to make DeviceIoControl() tell us
* the required size. NtFsControlFile() does have such a feature,
string->len = 0;
string->str = NULL;
- g_string_maybe_expand (string, MAX (dfl_size, 2));
+ g_string_maybe_expand (string, MAX (dfl_size, 64));
string->str[0] = 0;
return string;
{
gchar **gecos_fields;
gchar **name_parts;
+ gchar *uppercase_pw_name;
/* split the gecos field and substitute '&' */
gecos_fields = g_strsplit (pw->pw_gecos, ",", 0);
name_parts = g_strsplit (gecos_fields[0], "&", 0);
- pw->pw_name[0] = g_ascii_toupper (pw->pw_name[0]);
- e.real_name = g_strjoinv (pw->pw_name, name_parts);
+ uppercase_pw_name = g_strdup (pw->pw_name);
+ uppercase_pw_name[0] = g_ascii_toupper (uppercase_pw_name[0]);
+ e.real_name = g_strjoinv (uppercase_pw_name, name_parts);
g_strfreev (gecos_fields);
g_strfreev (name_parts);
+ g_free (uppercase_pw_name);
}
#endif
for (i = 0; i < n_children; i++)
{
- TYPE_CHECK (children[i], child_type, NULL);
+ if G_UNLIKELY (!g_variant_is_of_type (children[i], child_type))
+ {
+ while (i != 0)
+ g_variant_unref (my_children[--i]);
+ g_free (my_children);
+ g_return_val_if_fail (g_variant_is_of_type (children[i], child_type), NULL);
+ }
my_children[i] = g_variant_ref_sink (children[i]);
trusted &= g_variant_is_trusted (children[i]);
}
#define GVSB_MAGIC ((gsize) 1033660112u)
#define GVSB_MAGIC_PARTIAL ((gsize) 2942751021u)
#define GVHB_MAGIC ((gsize) 3087242682u)
-#define is_valid_builder(b) (b != NULL && \
- GVSB(b)->magic == GVSB_MAGIC)
+#define is_valid_builder(b) (GVSB(b)->magic == GVSB_MAGIC)
#define is_valid_heap_builder(b) (GVHB(b)->magic == GVHB_MAGIC)
/* Just to make sure that by adding a union to GVariantBuilder, we
static gboolean
ensure_valid_builder (GVariantBuilder *builder)
{
- if (is_valid_builder (builder))
+ if (builder == NULL)
+ return FALSE;
+ else if (is_valid_builder (builder))
return TRUE;
if (builder->u.s.partial_magic == GVSB_MAGIC_PARTIAL)
{
#define GVSD_MAGIC ((gsize) 2579507750u)
#define GVSD_MAGIC_PARTIAL ((gsize) 3488698669u)
#define GVHD_MAGIC ((gsize) 2450270775u)
-#define is_valid_dict(d) (d != NULL && \
- GVSD(d)->magic == GVSD_MAGIC)
+#define is_valid_dict(d) (GVSD(d)->magic == GVSD_MAGIC)
#define is_valid_heap_dict(d) (GVHD(d)->magic == GVHD_MAGIC)
/* Just to make sure that by adding a union to GVariantDict, we didn't
static gboolean
ensure_valid_dict (GVariantDict *dict)
{
- if (is_valid_dict (dict))
+ if (dict == NULL)
+ return FALSE;
+ else if (is_valid_dict (dict))
return TRUE;
if (dict->u.s.partial_magic == GVSD_MAGIC_PARTIAL)
{
endif
subdir('gnulib')
- gnulib_objects = [gnulib_lib.extract_all_objects()]
+ gnulib_objects = [gnulib_lib.extract_all_objects(recursive: false)]
endif
glib_headers = files(
libglib = library('glib-2.0',
glib_dtrace_obj, glib_dtrace_hdr,
sources : [deprecated_sources, glib_sources],
- objects : [charset_lib.extract_all_objects()] + gnulib_objects,
+ objects : [charset_lib.extract_all_objects(recursive: false)] + gnulib_objects,
version : library_version,
soversion : soversion,
darwin_versions : darwin_versions,
{
class->set_property (object, param_id, &tmp_value, pspec);
- if (~pspec->flags & G_PARAM_EXPLICIT_NOTIFY)
- {
- GParamSpec *notify_pspec;
-
- notify_pspec = get_notify_pspec (pspec);
-
- if (notify_pspec != NULL)
- g_object_notify_queue_add (object, nqueue, notify_pspec);
- }
+ if (~pspec->flags & G_PARAM_EXPLICIT_NOTIFY &&
+ pspec->flags & G_PARAM_READABLE)
+ g_object_notify_queue_add (object, nqueue, pspec);
}
g_value_unset (&tmp_value);
}
g_object_ref (object);
+ memset (values, 0, n_properties * sizeof (GValue));
+
obj_type = G_OBJECT_TYPE (object);
for (i = 0; i < n_properties; i++)
{
- pspec = g_param_spec_pool_lookup (pspec_pool,
- names[i],
- obj_type,
- TRUE);
+ pspec = g_param_spec_pool_lookup (pspec_pool, names[i], obj_type, TRUE);
if (!g_object_get_is_valid_property (object, pspec, names[i]))
break;
-
- memset (&values[i], 0, sizeof (GValue));
g_value_init (&values[i], pspec->value_type);
object_get_property (object, pspec, &values[i]);
}
g_return_val_if_fail (g_class != NULL, NULL);
node = lookup_type_node_I (G_TYPE_FROM_CLASS (g_class));
+
+ g_return_val_if_fail (node != NULL, NULL);
+
/* We used to acquire a read lock here. That is not necessary, since
* parent->data->class.class is constant as long as the derived class
* exists.
*/
- if (node && node->is_classed && node->data && NODE_PARENT_TYPE (node))
+ if (node->is_classed && node->data && NODE_PARENT_TYPE (node))
{
node = lookup_type_node_I (NODE_PARENT_TYPE (node));
class = node->data->class.class;
project('glib', 'c', 'cpp',
- version : '2.70.0',
+ version : '2.70.1',
# NOTE: We keep this pinned at 0.49 because that's what Debian 10 ships
meson_version : '>= 0.49.2',
default_options : [
[wrap-git]
directory=proxy-libintl
url=https://github.com/frida/proxy-libintl.git
-revision=0.1
+revision=0.2
depth=1