mirror of https://gitee.com/openkylin/glib2.0.git
247 lines
6.0 KiB
C
247 lines
6.0 KiB
C
|
/*
|
|||
|
* Copyright © 2020 Endless OS Foundation, LLC
|
|||
|
*
|
|||
|
* This library is free software; you can redistribute it and/or
|
|||
|
* modify it under the terms of the GNU Lesser General Public
|
|||
|
* License as published by the Free Software Foundation; either
|
|||
|
* version 2.1 of the License, or (at your option) any later version.
|
|||
|
*
|
|||
|
* This library is distributed in the hope that it will be useful,
|
|||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|||
|
* Lesser General Public License for more details.
|
|||
|
*
|
|||
|
* You should have received a copy of the GNU Lesser General Public
|
|||
|
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
|||
|
*
|
|||
|
* Author: Philip Withnall <withnall@endlessm.com>
|
|||
|
*/
|
|||
|
|
|||
|
/* This modelling file needs to be uploaded to GLib’s Coverity configuration at
|
|||
|
* https://scan.coverity.com/projects/glib?tab=analysis_settings
|
|||
|
* by someone with the appropriate permissions on Coverity. It should be kept in
|
|||
|
* sync with what’s there.
|
|||
|
*
|
|||
|
* Reference: https://scan.coverity.com/tune
|
|||
|
*/
|
|||
|
|
|||
|
/* Disable some esoteric options which Coverity doesn't understand because they
|
|||
|
* delve into assembly. */
|
|||
|
#define NVALGRIND 1
|
|||
|
#undef HAVE_DTRACE
|
|||
|
|
|||
|
#define TRACE(probe) /* no-op */
|
|||
|
|
|||
|
/* libc definitions */
|
|||
|
#define NULL ((void*)0)
|
|||
|
|
|||
|
void *malloc (size_t);
|
|||
|
void *calloc (size_t, size_t);
|
|||
|
void *realloc (void *, size_t);
|
|||
|
void free (void *);
|
|||
|
|
|||
|
/* Define some standard GLib types. */
|
|||
|
typedef size_t gsize;
|
|||
|
typedef char gchar;
|
|||
|
typedef unsigned char guchar;
|
|||
|
typedef int gint;
|
|||
|
typedef unsigned long gulong;
|
|||
|
typedef unsigned int guint32;
|
|||
|
typedef void* gpointer;
|
|||
|
typedef unsigned int gboolean;
|
|||
|
|
|||
|
typedef enum
|
|||
|
{
|
|||
|
/* log flags */
|
|||
|
G_LOG_FLAG_RECURSION = 1 << 0,
|
|||
|
G_LOG_FLAG_FATAL = 1 << 1,
|
|||
|
|
|||
|
/* GLib log levels */
|
|||
|
G_LOG_LEVEL_ERROR = 1 << 2, /* always fatal */
|
|||
|
G_LOG_LEVEL_CRITICAL = 1 << 3,
|
|||
|
G_LOG_LEVEL_WARNING = 1 << 4,
|
|||
|
G_LOG_LEVEL_MESSAGE = 1 << 5,
|
|||
|
G_LOG_LEVEL_INFO = 1 << 6,
|
|||
|
G_LOG_LEVEL_DEBUG = 1 << 7,
|
|||
|
|
|||
|
G_LOG_LEVEL_MASK = ~(G_LOG_FLAG_RECURSION | G_LOG_FLAG_FATAL)
|
|||
|
} GLogLevelFlags;
|
|||
|
|
|||
|
typedef struct _GList GList;
|
|||
|
|
|||
|
struct _GList
|
|||
|
{
|
|||
|
gpointer data;
|
|||
|
GList *next;
|
|||
|
GList *prev;
|
|||
|
};
|
|||
|
|
|||
|
typedef struct _GError GError;
|
|||
|
|
|||
|
struct _GError
|
|||
|
{
|
|||
|
/* blah */
|
|||
|
};
|
|||
|
|
|||
|
/* Dummied from sys/stat.h. */
|
|||
|
struct stat {};
|
|||
|
extern int stat (const char *path, struct stat *buf);
|
|||
|
|
|||
|
/* g_stat() can be used to check whether a given path is safe (i.e. exists).
|
|||
|
* This is not a full solution for sanitising user-provided paths, but goes a
|
|||
|
* long way, and is the best we can do without more context about how the path
|
|||
|
* is used. */
|
|||
|
typedef struct stat GStatBuf;
|
|||
|
#undef g_stat
|
|||
|
|
|||
|
int
|
|||
|
g_stat (const char *filename, GStatBuf *buf)
|
|||
|
{
|
|||
|
__coverity_tainted_string_sanitize_content__ (filename);
|
|||
|
return stat (filename, buf);
|
|||
|
}
|
|||
|
|
|||
|
/* g_path_skip_root() can be used to validate that a @file_name is absolute. It
|
|||
|
* returns %NULL otherwise. */
|
|||
|
const char *
|
|||
|
g_path_skip_root (const char *file_name)
|
|||
|
{
|
|||
|
int is_ok;
|
|||
|
if (is_ok)
|
|||
|
{
|
|||
|
__coverity_tainted_string_sanitize_content__ (file_name);
|
|||
|
return file_name;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
return 0; /* NULL */
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/* Tainted string sanitiser. */
|
|||
|
int
|
|||
|
g_action_name_is_valid (const char *action_name)
|
|||
|
{
|
|||
|
int is_ok;
|
|||
|
if (is_ok)
|
|||
|
{
|
|||
|
__coverity_tainted_string_sanitize_content__ (action_name);
|
|||
|
return 1; /* TRUE */
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
return 0; /* FALSE */
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/* Treat this like an assert(0). */
|
|||
|
void
|
|||
|
g_return_if_fail_warning (const char *log_domain,
|
|||
|
const char *pretty_function,
|
|||
|
const char *expression)
|
|||
|
{
|
|||
|
__coverity_panic__();
|
|||
|
}
|
|||
|
|
|||
|
/* Treat this like an assert(0). */
|
|||
|
void
|
|||
|
g_log (const gchar *log_domain,
|
|||
|
GLogLevelFlags log_level,
|
|||
|
const gchar *format,
|
|||
|
...)
|
|||
|
{
|
|||
|
if (log_level & G_LOG_LEVEL_CRITICAL)
|
|||
|
__coverity_panic__ ();
|
|||
|
}
|
|||
|
|
|||
|
#define g_critical(...) __coverity_panic__ ();
|
|||
|
|
|||
|
/* Treat it as a memory sink to hide one-time allocation leaks. */
|
|||
|
void
|
|||
|
(g_once_init_leave) (volatile void *location,
|
|||
|
gsize result)
|
|||
|
{
|
|||
|
__coverity_escape__ (result);
|
|||
|
}
|
|||
|
|
|||
|
/* Coverity cannot model allocation management for linked lists, so just pretend
|
|||
|
* that it's a pass-through. */
|
|||
|
GList *
|
|||
|
g_list_reverse (GList *list)
|
|||
|
{
|
|||
|
return list;
|
|||
|
}
|
|||
|
|
|||
|
/* g_ascii_isspace() routinely throws data_index taint errors, saying that
|
|||
|
* tainted data is being used to index g_ascii_table. This is true, but the
|
|||
|
* table has defined values for all possible 8-bit indexes. */
|
|||
|
gboolean
|
|||
|
g_ascii_isspace (gchar c)
|
|||
|
{
|
|||
|
int is_space;
|
|||
|
__coverity_tainted_string_sink_content__ (c);
|
|||
|
if (is_space)
|
|||
|
return 1;
|
|||
|
else
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
/* Coverity treats byte-swapping operations as suspicious, and taints all data
|
|||
|
* which is byte-swapped (because it thinks it therefore probably comes from an
|
|||
|
* external source, which is reasonable). That is not the case for checksum
|
|||
|
* calculation, however.
|
|||
|
*
|
|||
|
* Since the definitions of these two functions depends on the host byte order,
|
|||
|
* just model them as no-ops. */
|
|||
|
void
|
|||
|
md5_byte_reverse (guchar *buffer,
|
|||
|
gulong length)
|
|||
|
{
|
|||
|
/* No-op. */
|
|||
|
}
|
|||
|
|
|||
|
void
|
|||
|
sha_byte_reverse (guint32 *buffer,
|
|||
|
gint length)
|
|||
|
{
|
|||
|
/* No-op. */
|
|||
|
}
|
|||
|
|
|||
|
/* Parse error printing does not care about sanitising the input. */
|
|||
|
gchar *
|
|||
|
g_variant_parse_error_print_context (GError *error,
|
|||
|
const gchar *source_str)
|
|||
|
{
|
|||
|
__coverity_tainted_data_sink__ (source_str);
|
|||
|
return __coverity_alloc_nosize__ ();
|
|||
|
}
|
|||
|
|
|||
|
/* Coverity somehow analyses G_LIKELY(x) as sometimes meaning !x, for example
|
|||
|
* when analysing g_try_realloc(). Ignore that. */
|
|||
|
#define G_LIKELY(x) x
|
|||
|
#define G_UNLIKELY(x) x
|
|||
|
|
|||
|
typedef struct {} DIR;
|
|||
|
typedef struct _GDir GDir;
|
|||
|
|
|||
|
struct _GDir
|
|||
|
{
|
|||
|
DIR *dirp;
|
|||
|
};
|
|||
|
|
|||
|
/* This is a private function to libglib, and Coverity can’t peek inside it when
|
|||
|
* analysing code in (say) GIO. */
|
|||
|
GDir *
|
|||
|
g_dir_new_from_dirp (gpointer dirp)
|
|||
|
{
|
|||
|
GDir *dir;
|
|||
|
|
|||
|
if (dirp == 0)
|
|||
|
__coverity_panic__();
|
|||
|
|
|||
|
dir = malloc (sizeof (GDir));
|
|||
|
dir->dirp = dirp;
|
|||
|
|
|||
|
return dir;
|
|||
|
}
|