Coverage Report

Created: 2026-02-26 07:02

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libredwg/src/bits.h
Line
Count
Source
1
/*****************************************************************************/
2
/*  LibreDWG - free implementation of the DWG file format                    */
3
/*                                                                           */
4
/*  Copyright (C) 2009-2025 Free Software Foundation, Inc.                   */
5
/*                                                                           */
6
/*  This library is free software, licensed under the terms of the GNU       */
7
/*  General Public License as published by the Free Software Foundation,     */
8
/*  either version 3 of the License, or (at your option) any later version.  */
9
/*  You should have received a copy of the GNU General Public License        */
10
/*  along with this program.  If not, see <http://www.gnu.org/licenses/>.    */
11
/*****************************************************************************/
12
13
/*
14
 * bits.c: low level read and write function prototypes
15
 * written by Felipe Castro
16
 * modified by Felipe CorrĂȘa da Silva Sances
17
 * modified by Rodrigo Rodrigues da Silva
18
 * modified by Reini Urban
19
 */
20
21
/**
22
 The position of bits within bytes is numerically ordered as depicted below:
23
24
\code
25
 position: 01234567 01234567 01234567 ...
26
 bits:     76543210 76543210 76543210 ...
27
           \______/ \______/ \______/
28
            byte 1   byte 2   byte 3  ...
29
\endcode
30
(i.e. little endian)
31
 */
32
33
#ifndef BITS_H
34
#define BITS_H
35
36
#include "config.h"
37
#ifdef HAVE_WCHAR_H
38
// cross-compilation problem:
39
// /usr/lib/gcc/arm-linux-gnueabi/9/include-fixed/limits.h defines it as 1
40
#  if defined(MB_LEN_MAX) && MB_LEN_MAX != 16 && MB_LEN_MAX != 32
41
#    undef MB_LEN_MAX
42
#    define MB_LEN_MAX 16
43
#  endif
44
#  include <wchar.h>
45
#endif
46
#include <stdio.h>
47
#include <string.h>
48
#include <stddef.h>
49
#include <stdbool.h>
50
#include "common.h"
51
#include "dwg.h"
52
53
// DWG size limitations, invalid sizes and offsets
54
#if SIZEOF_SIZE_T == 8
55
1.69G
#  define MAX_MEM_ALLOC 0x10000000000
56
#else
57
#  define MAX_MEM_ALLOC 0xF0000000
58
#endif
59
60
// avoid double linkage on windows with unit-testing
61
#if defined(BITS_TEST_C) || defined(DECODE_TEST_C) || defined(DXF_TEST_C)
62
#  undef EXPORT
63
#  define EXPORT
64
#endif
65
66
/**
67
 Structure for DWG-files raw data streams.
68
 */
69
typedef struct _bit_chain
70
{
71
  unsigned char *chain;
72
  size_t size;
73
  size_t byte;
74
  unsigned char bit;
75
  unsigned char opts; // from dwg->opts, see DWG_OPTS_*
76
  Dwg_Version_Type version;
77
  Dwg_Version_Type from_version;
78
  FILE *fh;
79
  BITCODE_RS codepage;
80
} Bit_Chain;
81
82
#define EMPTY_CHAIN(size)                                                     \
83
  {                                                                           \
84
    NULL, size, 0UL, 0, 0, R_INVALID, R_INVALID, NULL, 0                      \
85
  }
86
87
// only if from r2007+ DWG. not JSON, DXF (FIXME TABLE.name). add API converts
88
// to TU
89
#define IS_FROM_TU(dat)                                                       \
90
7.05k
  (dat->from_version >= R_2007) && !(dat->opts & DWG_OPTS_IN)
91
#define IS_FROM_TU_DWG(dwg)                                                   \
92
43.7k
  (dwg->header.from_version >= R_2007) && !(dwg->opts & DWG_OPTS_IN)
93
#define TU_to_int(b) le16toh (((uint16_t)b[1] << 8) + b[0])
94
95
/* Functions for raw data manipulations.
96
 */
97
void bit_advance_position (Bit_Chain *dat, long advance);
98
size_t bit_position (Bit_Chain *dat);
99
void bit_set_position (Bit_Chain *dat, size_t bitpos);
100
void bit_reset_chain (Bit_Chain *dat);
101
102
BITCODE_B bit_read_B (Bit_Chain *dat);
103
void bit_write_B (Bit_Chain *dat, unsigned char value);
104
105
BITCODE_BB bit_read_BB (Bit_Chain *dat);
106
void bit_write_BB (Bit_Chain *dat, unsigned char value);
107
108
BITCODE_4BITS bit_read_4BITS (Bit_Chain *dat);
109
void bit_write_4BITS (Bit_Chain *dat, unsigned char value);
110
111
BITCODE_RC bit_read_RC (Bit_Chain *dat);
112
void bit_write_RC (Bit_Chain *dat, unsigned char value);
113
114
BITCODE_RS bit_read_RS (Bit_Chain *dat);
115
void bit_write_RS (Bit_Chain *dat, BITCODE_RS value);
116
BITCODE_BS bit_read_RS_BE (Bit_Chain *dat);
117
void bit_write_RS_BE (Bit_Chain *dat, BITCODE_BS value);
118
119
BITCODE_RL bit_read_RL (Bit_Chain *dat);
120
BITCODE_RL bit_read_RL_BE (Bit_Chain *dat);
121
void bit_write_RL (Bit_Chain *dat, BITCODE_RL value);
122
void bit_write_RL_BE (Bit_Chain *dat, BITCODE_RL value);
123
124
BITCODE_RLL bit_read_RLL (Bit_Chain *dat);
125
BITCODE_RLL bit_read_RLL_BE (Bit_Chain *dat);
126
0
#define bit_read_RLLd(dat) (BITCODE_RLLd) bit_read_RLL (dat)
127
void bit_write_RLL (Bit_Chain *dat, BITCODE_RLL value);
128
#define bit_write_RLLd(dat, value) bit_write_RLL (dat, (BITCODE_RLL)value)
129
void bit_write_RLL_BE (Bit_Chain *dat, BITCODE_RLL value);
130
131
BITCODE_RD bit_read_RD (Bit_Chain *dat);
132
void bit_write_RD (Bit_Chain *dat, BITCODE_RD value);
133
134
/* Functions for manipulating compacted data
135
 */
136
BITCODE_BS bit_read_BS (Bit_Chain *dat);
137
void bit_write_BS (Bit_Chain *dat, BITCODE_BS value);
138
139
BITCODE_BL bit_read_BL (Bit_Chain *dat);
140
void bit_write_BL (Bit_Chain *dat, BITCODE_BL value);
141
0
#define bit_read_BLd(dat) (BITCODE_BLd) bit_read_BL (dat)
142
void bit_write_BLd (Bit_Chain *dat, BITCODE_BLd value);
143
144
BITCODE_BS bit_read_BOT (Bit_Chain *dat);
145
void bit_write_BOT (Bit_Chain *dat, BITCODE_BS value);
146
147
BITCODE_BLL bit_read_BLL (Bit_Chain *dat);
148
void bit_write_BLL (Bit_Chain *dat, BITCODE_BLL value);
149
150
#if 0
151
BITCODE_3B bit_read_3B (Bit_Chain *dat);
152
void bit_write_3B (Bit_Chain *dat, unsigned char value);
153
BITCODE_BLL bit_read_3BLL (Bit_Chain *dat); /*unused but as documented*/
154
void bit_write_3BLL (Bit_Chain *dat, BITCODE_BLL value);
155
#endif
156
157
BITCODE_BD bit_read_BD (Bit_Chain *dat);
158
void bit_write_BD (Bit_Chain *dat, BITCODE_BD value);
159
160
BITCODE_MC bit_read_MC (Bit_Chain *dat);
161
void bit_write_MC (Bit_Chain *dat, BITCODE_MC value);
162
163
BITCODE_UMC bit_read_UMC (Bit_Chain *dat);
164
void bit_write_UMC (Bit_Chain *dat, BITCODE_UMC value);
165
166
BITCODE_MS bit_read_MS (Bit_Chain *dat);
167
void bit_write_MS (Bit_Chain *dat, BITCODE_MS value);
168
169
void bit_read_BE (Bit_Chain *restrict dat, double *restrict x,
170
                  double *restrict y, double *restrict z);
171
void bit_write_BE (Bit_Chain *dat, double x, double y, double z);
172
void normalize_BE (BITCODE_3BD ext);
173
174
BITCODE_DD bit_read_DD (Bit_Chain *dat, double default_value);
175
BITCODE_BB bit_write_DD (Bit_Chain *dat, double value, double default_value);
176
int bit_eq_DD (double value, double default_value);
177
178
BITCODE_BT bit_read_BT (Bit_Chain *dat);
179
void bit_write_BT (Bit_Chain *dat, double value);
180
181
int bit_read_H (Bit_Chain *restrict dat, Dwg_Handle *restrict handle);
182
void bit_write_H (Bit_Chain *restrict dat, Dwg_Handle *restrict handle);
183
void bit_H_to_dat (Bit_Chain *restrict dat, Dwg_Handle *restrict handle);
184
185
uint16_t bit_read_CRC (Bit_Chain *dat);
186
187
int bit_check_CRC (Bit_Chain *dat, size_t start_address, const uint16_t seed);
188
uint16_t bit_write_CRC (Bit_Chain *dat, size_t start_address,
189
                        const uint16_t seed);
190
// object-map only
191
uint16_t bit_write_CRC_BE (Bit_Chain *dat, size_t start_address,
192
                           const uint16_t seed);
193
194
uint16_t bit_calc_CRC (const uint16_t seed, unsigned char *adr, size_t len);
195
uint32_t bit_calc_CRC32 (const uint32_t seed, unsigned char *adr, size_t len);
196
197
int bit_read_fixed (Bit_Chain *restrict dat, BITCODE_RC *restrict dest,
198
                    size_t length);
199
200
/* read fixed-length ASCII string */
201
BITCODE_TF bit_read_TF (Bit_Chain *dat, size_t length) ATTRIBUTE_MALLOC;
202
BITCODE_TF bit_read_bits (Bit_Chain *dat, size_t bits) ATTRIBUTE_MALLOC;
203
void bit_write_bits (Bit_Chain *restrict dat, BITCODE_TF restrict bits,
204
                     size_t numbits);
205
206
void bit_write_TF (Bit_Chain *restrict dat, BITCODE_TF restrict chain,
207
                   size_t length);
208
/** Write fixed-length text from variable length string
209
    (possibly downgraded from shorter string).
210
 */
211
void bit_write_TFv (Bit_Chain *restrict dat, BITCODE_TF restrict chain,
212
                    size_t length);
213
214
/* read ASCII string, with length as BS */
215
BITCODE_TV bit_read_TV (Bit_Chain *restrict dat);
216
217
void bit_write_TV (Bit_Chain *restrict dat, BITCODE_TV restrict value);
218
219
/* read UCS-2 string, with length as BS */
220
BITCODE_TU bit_read_TU (Bit_Chain *restrict dat) ATTRIBUTE_MALLOC;
221
BITCODE_TU bit_read_TU_len (Bit_Chain *restrict dat,
222
                            unsigned int *lenp) ATTRIBUTE_MALLOC;
223
BITCODE_TU bit_read_TU_size (Bit_Chain *restrict dat,
224
                             unsigned int len) ATTRIBUTE_MALLOC;
225
226
/* read ASCII string, with length as RS */
227
BITCODE_T16 bit_read_T16 (Bit_Chain *restrict dat) ATTRIBUTE_MALLOC;
228
/* read UCS-2 string, with length as RS */
229
BITCODE_TU bit_read_TU16 (Bit_Chain *restrict dat) ATTRIBUTE_MALLOC;
230
/* read ASCII/UCS-2 string, with length as RL */
231
BITCODE_T32 bit_read_T32 (Bit_Chain *restrict dat) ATTRIBUTE_MALLOC;
232
/* read ASCII/UCS-4 string, with length as RL */
233
BITCODE_TU32 bit_read_TU32 (Bit_Chain *restrict dat) ATTRIBUTE_MALLOC;
234
235
void bit_write_TU (Bit_Chain *restrict dat, BITCODE_TU restrict value);
236
void bit_write_TU16 (Bit_Chain *restrict dat, BITCODE_TU restrict value);
237
void bit_write_T16 (Bit_Chain *restrict dat, BITCODE_T16 restrict value);
238
void bit_write_T32 (Bit_Chain *restrict dat, BITCODE_T32 restrict value);
239
void bit_write_TU32 (Bit_Chain *restrict dat, BITCODE_TU32 restrict value);
240
241
BITCODE_T bit_read_T (Bit_Chain *restrict dat) ATTRIBUTE_MALLOC;
242
void bit_write_T (Bit_Chain *restrict dat, BITCODE_T restrict chain);
243
244
/* Converts UCS-2 to ASCII (with \U+XXXX), returning a copy. */
245
EXPORT char *bit_embed_TU (BITCODE_TU restrict wstr) ATTRIBUTE_MALLOC;
246
EXPORT char *bit_embed_TU_size (BITCODE_TU restrict wstr,
247
                                const int len) ATTRIBUTE_MALLOC;
248
249
#ifdef HAVE_NATIVE_WCHAR2
250
#  define bit_wcs2len(wstr) wcslen (wstr)
251
#  ifdef HAVE_WCSNLEN
252
#    define bit_wcs2nlen(wstr, maxlen) wcsnlen (wstr, maxlen)
253
#  else
254
size_t bit_wcs2nlen (const BITCODE_TU restrict wstr, const size_t maxlen);
255
#  endif
256
#  define bit_wcs2cpy(dest, src) wcscpy (dest, src)
257
#  ifdef _WIN32
258
#    define bit_wcs2dup(src) _wcsdup (src)
259
#  else
260
#    define bit_wcs2dup(src) wcsdup (src)
261
#  endif
262
#  define bit_wcs2cmp(dest, src) wcscmp (s1, s2)
263
#else
264
/* length of UCS-2 string */
265
size_t bit_wcs2len (const BITCODE_TU restrict wstr);
266
/* bounded length of UCS-2 string. stops scanning at maxlen.
267
   Beware: might overflow to negative lengths */
268
size_t bit_wcs2nlen (const BITCODE_TU restrict wstr, const size_t maxlen);
269
BITCODE_TU bit_wcs2cpy (BITCODE_TU restrict dest,
270
                        const BITCODE_TU restrict src);
271
BITCODE_TU bit_wcs2dup (const BITCODE_TU restrict src);
272
int bit_wcs2cmp (BITCODE_TU restrict s1, const BITCODE_TU restrict s2);
273
#endif
274
275
#ifndef HAVE_STRNLEN
276
size_t bit_strnlen (const char *restrict str, const size_t maxlen);
277
#  define strnlen(str, maxlen) bit_strnlen (str, maxlen)
278
#endif
279
280
/* Convert UCS-2LE to UTF-8, returning a copy. */
281
EXPORT char *bit_convert_TU (const BITCODE_TU restrict wstr) ATTRIBUTE_MALLOC;
282
EXPORT char *bit_TU_to_utf8_len (const BITCODE_TU restrict wstr,
283
                                 const int len) ATTRIBUTE_MALLOC;
284
285
/** Converts UTF-8 (dxf,json) to ASCII TV.
286
    \uxxxx or other unicode => \U+XXXX if not representable in this codepage.
287
    If cquoted unquotes \" to ", undo json_cquote(),
288
    Returns NULL if not enough room in dest. */
289
EXPORT char *bit_utf8_to_TV (char *restrict dest,
290
                             const unsigned char *restrict src,
291
                             const size_t destlen, const size_t srclen,
292
                             const unsigned cquoted,
293
                             const BITCODE_RS codepage);
294
/** converts old codepage'd strings to UTF-8.
295
    convert \U+XXXX or \MnXXXX also if representable.
296
    returns NULL on errors, or the unchanged src string, or a copy.
297
 */
298
EXPORT
299
char *bit_TV_to_utf8 (const char *restrict src,
300
                      const BITCODE_RS codepage) ATTRIBUTE_MALLOC;
301
302
/** Converts UTF-8 to UCS-2. Returns a copy.
303
    Needed by dwg importers, writers (e.g. dxf2dwg)
304
    cquoted is needed by in_json, to unquote \"
305
 */
306
EXPORT BITCODE_TU bit_utf8_to_TU (char *restrict str,
307
                                  const unsigned cquoted) ATTRIBUTE_MALLOC;
308
// convert all \\U+XXXX and \\M+nXXXX sequences to UTF-8
309
const char *bit_u_expand (const char *src);
310
311
/* compare an ASCII/TU string to ASCII name */
312
int bit_eq_T (Bit_Chain *restrict dat, const BITCODE_T restrict str1,
313
              const char *restrict str2);
314
/* compare an ASCII/utf-8 string to a r2007+ name */
315
int bit_eq_TU (const char *str, BITCODE_TU restrict wstr);
316
/* check if the string (ascii or unicode) is empty */
317
int bit_empty_T (Bit_Chain *restrict dat, BITCODE_T restrict str);
318
BITCODE_T bit_set_T (Bit_Chain *restrict dat, const char *restrict src);
319
320
BITCODE_TIMEBLL bit_read_TIMEBLL (Bit_Chain *dat);
321
void bit_write_TIMEBLL (Bit_Chain *dat, BITCODE_TIMEBLL date);
322
323
BITCODE_TIMERLL bit_read_TIMERLL (Bit_Chain *dat);
324
void bit_write_TIMERLL (Bit_Chain *dat, BITCODE_TIMERLL date);
325
326
int bit_read_CMC (Bit_Chain *dat, Bit_Chain *str_dat,
327
                  Dwg_Color *restrict color);
328
void bit_write_CMC (Bit_Chain *dat, Bit_Chain *str_dat,
329
                    Dwg_Color *restrict color);
330
// Convert from truecolor (r2004+) to palette (-r2000)
331
void bit_downconvert_CMC (Bit_Chain *dat, Dwg_Color *restrict color);
332
void bit_upconvert_CMC (Bit_Chain *dat, Dwg_Color *restrict color);
333
334
void bit_read_ENC (Bit_Chain *dat, Bit_Chain *hdl_dat, Bit_Chain *str_dat,
335
                   Dwg_Color *restrict color);
336
void bit_write_ENC (Bit_Chain *dat, Bit_Chain *hdl_dat, Bit_Chain *str_dat,
337
                    Dwg_Color *restrict color);
338
339
int bit_search_sentinel (Bit_Chain *dat, const unsigned char sentinel[16]);
340
341
void bit_chain_init (Bit_Chain *dat, const size_t size);
342
void bit_chain_init_dat (Bit_Chain *restrict dat, const size_t size,
343
                         const Bit_Chain *restrict from_dat);
344
void bit_chain_alloc (Bit_Chain *dat);
345
void bit_chain_alloc_size (Bit_Chain *dat, const size_t size);
346
void bit_chain_free (Bit_Chain *dat);
347
// after bit_chain_init
348
#define bit_chain_set_version(to, from)                                       \
349
2.85k
  (to)->opts = (from)->opts;                                                  \
350
2.85k
  (to)->version = (from)->version;                                            \
351
2.85k
  (to)->from_version = (from)->from_version;                                  \
352
2.85k
  (to)->fh = (from)->fh;                                                      \
353
2.85k
  (to)->codepage = (from)->codepage
354
355
void bit_print (Bit_Chain *dat, size_t size);
356
357
void bit_write_bits1 (Bit_Chain *restrict dat, const char *restrict bits);
358
long bit_write_hexbits (Bit_Chain *restrict dat, const char *restrict bytes);
359
void bit_print_bits (unsigned char *bits, size_t bitsize);
360
void bit_fprint_bits (FILE *fp, unsigned char *bits, size_t bitsize);
361
void bit_explore_chain (Bit_Chain *dat, size_t from, size_t size);
362
363
BITCODE_BD bit_nan (void);
364
int bit_isnan (BITCODE_BD number);
365
366
// which would require different text sizes and recalc.
367
bool does_cross_unicode_datversion (Bit_Chain *restrict dat);
368
/* Copy the whole content of tmp_data to dat, and reset tmp_dat */
369
void bit_copy_chain (Bit_Chain *restrict orig_dat,
370
                     Bit_Chain *restrict tmp_dat);
371
372
// for in_dxf and in_json
373
size_t in_hex2bin (unsigned char *restrict dest, char *restrict src,
374
                   size_t destlen) __nonnull_all;
375
376
// if there's a high char (> 0x7f)
377
bool bit_TF_contains_high (char *s, size_t len);
378
379
#endif // BITS_H