Bug Summary

File:_build/../src/bterowdata.cc
Warning:line 55, column 9
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name bterowdata.cc -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mframe-pointer=none -relaxed-aliasing -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/_build -resource-dir /usr/lib/llvm-16/lib/clang/16 -I src/libbte-2.91.so.0.6500.0.p -I src -I ../src -I . -I .. -I src/bte -I ../src/bte -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/sysprof-6 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/pango-1.0 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/fribidi -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/p11-kit-1 -I /usr/include/ctk-3.0 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/x86_64-linux-gnu -I /usr/include/webp -I /usr/include/gio-unix-2.0 -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib/x86_64-linux-gnu/dbus-1.0/include -D _GLIBCXX_ASSERTIONS=1 -D _FILE_OFFSET_BITS=64 -D G_LOG_DOMAIN="BTE" -D LOCALEDIR="/usr/local/share/locale" -D BTE_DISABLE_DEPRECATION_WARNINGS -D BTE_COMPILATION -U PARSER_INCLUDE_NOP -D CDK_VERSION_MIN_REQUIRED=(G_ENCODE_VERSION(3,18)) -D CDK_VERSION_MAX_ALLOWED=(G_ENCODE_VERSION(3,20)) -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/13/../../../../include/x86_64-linux-gnu/c++/13 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/backward -internal-isystem /usr/lib/llvm-16/lib/clang/16/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/13/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O3 -Wno-address-of-packed-member -Wno-missing-field-initializers -Wno-packed -Wno-switch-enum -Wno-unused-parameter -Wwrite-strings -std=gnu++17 -fdeprecated-macro -fdebug-compilation-dir=/rootdir/_build -ferror-limit 19 -fvisibility=hidden -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -fcolor-diagnostics -vectorize-loops -vectorize-slp -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2024-08-05-222352-10670-1 -x c++ ../src/bterowdata.cc
1/*
2 * Copyright (C) 2002,2009 Red Hat, Inc.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 *
18 * Red Hat Author(s): Nalin Dahyabhai, Behdad Esfahbod
19 */
20
21#include <config.h>
22
23#include "debug.h"
24#include "bterowdata.hh"
25
26#include <string.h>
27
28#include <type_traits>
29
30/* This will be true now that BteCell is POD, but make sure it'll be true
31 * once that changes.
32 */
33static_assert(std::is_trivially_copy_constructible<BteCell>::value, "BteCell is not copy constructible");
34static_assert(std::is_trivially_move_constructible<BteCell>::value, "BteCell is not move constructible");
35static_assert(std::is_trivially_copyable<BteCell>::value, "BteCell is not trivially copyable");
36static_assert(std::is_trivially_copy_assignable<BteCell>::value, "BteCell is not copy assignable");
37static_assert(std::is_trivially_move_assignable<BteCell>::value, "BteCell is not move assignable");
38
39/*
40 * BteCells: A row's cell array
41 */
42
43typedef struct _BteCells BteCells;
44struct _BteCells {
45 guint32 alloc_len;
46 BteCell cells[1];
47};
48
49static inline BteCells *
50_bte_cells_for_cell_array (BteCell *cells)
51{
52 if (G_UNLIKELY (!cells)(__builtin_expect (__extension__ ({ int _g_boolean_var_17; if
(!cells) _g_boolean_var_17 = 1; else _g_boolean_var_17 = 0; _g_boolean_var_17
; }), 0))
)
53 return NULL__null;
54
55 return (BteCells *) (((guchar *) cells) - G_STRUCT_OFFSET (BteCells, cells)((glong) __builtin_offsetof(BteCells, cells)));
Casting a non-structure type to a structure type and accessing a field can lead to memory access errors or data corruption
56}
57
58static BteCells *
59_bte_cells_realloc (BteCells *cells, guint32 len)
60{
61 guint32 alloc_len = (1 << g_bit_storage (MAX (len, 80))g_bit_storage_impl((((len) > (80)) ? (len) : (80)))) - 1;
62
63 _bte_debug_print(BTE_DEBUG_RING, "Enlarging cell array of %d cells to %d cells\n", cells ? cells->alloc_len : 0, alloc_len)do { } while(0);
64 cells = (BteCells *)g_realloc (cells, G_STRUCT_OFFSET (BteCells, cells)((glong) __builtin_offsetof(BteCells, cells)) + alloc_len * sizeof (cells->cells[0]));
65 cells->alloc_len = alloc_len;
66
67 return cells;
68}
69
70static void
71_bte_cells_free (BteCells *cells)
72{
73 _bte_debug_print(BTE_DEBUG_RING, "Freeing cell array of %d cells\n", cells->alloc_len)do { } while(0);
74 g_free (cells);
75}
76
77
78/*
79 * BteRowData: A row's data
80 */
81
82void
83_bte_row_data_init (BteRowData *row)
84{
85 memset (row, 0, sizeof (*row));
86}
87
88void
89_bte_row_data_clear (BteRowData *row)
90{
91 BteCell *cells = row->cells;
92 _bte_row_data_init (row);
93 row->cells = cells;
94}
95
96void
97_bte_row_data_fini (BteRowData *row)
98{
99 if (row->cells)
100 _bte_cells_free (_bte_cells_for_cell_array (row->cells));
101 row->cells = NULL__null;
102}
103
104static inline gboolean
105_bte_row_data_ensure (BteRowData *row, gulong len)
106{
107 BteCells *cells = _bte_cells_for_cell_array (row->cells);
108 if (G_LIKELY (cells && len <= cells->alloc_len)(__builtin_expect (__extension__ ({ int _g_boolean_var_18; if
(cells && len <= cells->alloc_len) _g_boolean_var_18
= 1; else _g_boolean_var_18 = 0; _g_boolean_var_18; }), 1))
)
109 return TRUE(!(0));
110
111 if (G_UNLIKELY (len >= 0xFFFF)(__builtin_expect (__extension__ ({ int _g_boolean_var_19; if
(len >= 0xFFFF) _g_boolean_var_19 = 1; else _g_boolean_var_19
= 0; _g_boolean_var_19; }), 0))
)
112 return FALSE(0);
113
114 row->cells = _bte_cells_realloc (cells, len)->cells;
115
116 return TRUE(!(0));
117}
118
119void
120_bte_row_data_insert (BteRowData *row, gulong col, const BteCell *cell)
121{
122 gulong i;
123
124 if (G_UNLIKELY (!_bte_row_data_ensure (row, row->len + 1))(__builtin_expect (__extension__ ({ int _g_boolean_var_20; if
(!_bte_row_data_ensure (row, row->len + 1)) _g_boolean_var_20
= 1; else _g_boolean_var_20 = 0; _g_boolean_var_20; }), 0))
)
125 return;
126
127 for (i = row->len; i > col; i--)
128 row->cells[i] = row->cells[i - 1];
129
130 row->cells[col] = *cell;
131 row->len++;
132}
133
134void _bte_row_data_append (BteRowData *row, const BteCell *cell)
135{
136 if (G_UNLIKELY (!_bte_row_data_ensure (row, row->len + 1))(__builtin_expect (__extension__ ({ int _g_boolean_var_21; if
(!_bte_row_data_ensure (row, row->len + 1)) _g_boolean_var_21
= 1; else _g_boolean_var_21 = 0; _g_boolean_var_21; }), 0))
)
137 return;
138
139 row->cells[row->len] = *cell;
140 row->len++;
141}
142
143void _bte_row_data_remove (BteRowData *row, gulong col)
144{
145 gulong i;
146
147 for (i = col + 1; i < row->len; i++)
148 row->cells[i - 1] = row->cells[i];
149
150 if (G_LIKELY (row->len)(__builtin_expect (__extension__ ({ int _g_boolean_var_22; if
(row->len) _g_boolean_var_22 = 1; else _g_boolean_var_22 =
0; _g_boolean_var_22; }), 1))
)
151 row->len--;
152}
153
154void _bte_row_data_fill (BteRowData *row, const BteCell *cell, gulong len)
155{
156 if (row->len < len) {
157 gulong i;
158
159 if (G_UNLIKELY (!_bte_row_data_ensure (row, len))(__builtin_expect (__extension__ ({ int _g_boolean_var_23; if
(!_bte_row_data_ensure (row, len)) _g_boolean_var_23 = 1; else
_g_boolean_var_23 = 0; _g_boolean_var_23; }), 0))
)
160 return;
161
162 for (i = row->len; i < len; i++)
163 row->cells[i] = *cell;
164
165 row->len = len;
166 }
167}
168
169void _bte_row_data_shrink (BteRowData *row, gulong max_len)
170{
171 if (max_len < row->len)
172 row->len = max_len;
173}
174
175void _bte_row_data_copy (const BteRowData *src, BteRowData *dst)
176{
177 _bte_row_data_ensure (dst, src->len);
178 dst->len = src->len;
179 dst->attr = src->attr;
180 memcpy(dst->cells, src->cells, src->len * sizeof (src->cells[0]));
181}
182
183/* Get the length, ignoring trailing empty cells (with a custom background color). */
184guint16 _bte_row_data_nonempty_length (const BteRowData *row)
185{
186 guint16 len;
187 const BteCell *cell;
188 for (len = row->len; len > 0; len--) {
189 cell = &row->cells[len - 1];
190 if (cell->attr.fragment() || cell->c != 0)
191 break;
192 }
193 return len;
194}
195