Coverage Report

Created: 2025-11-16 07:03

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libredwg/src/decode_r11.c
Line
Count
Source
1
/*****************************************************************************/
2
/*  LibreDWG - free implementation of the DWG file format                    */
3
/*                                                                           */
4
/*  Copyright (C) 2022-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
 * decode_r11.c: preR13 decoding
15
 * written by Reini Urban
16
 * modified by Michal Josef Špaček
17
 */
18
19
#include "config.h"
20
#ifndef _DEFAULT_SOURCE
21
#  define _DEFAULT_SOURCE 1 /* for byteswap.h */
22
#endif
23
#include <stdio.h>
24
#include <stdlib.h>
25
#include <string.h>
26
#include <stdbool.h>
27
#include <assert.h>
28
#include <limits.h>
29
30
#define IS_DECODER
31
#define _DECODE_R11_C
32
#ifdef USE_TRACING
33
/* This flag means we have checked the environment variable
34
   LIBREDWG_TRACE and set `loglevel' appropriately.  */
35
// static bool env_var_checked_p;
36
#endif /* USE_TRACING */
37
14.4M
#define DWG_LOGLEVEL loglevel
38
#include "logging.h"
39
#include "dwg_api.h" // for the preR13 add API
40
41
#include "common.h"
42
#include "bits.h"
43
#include "dwg.h"
44
#include "decode.h"
45
#include "free.h"
46
47
/* The logging level for the read (decode) path.
48
 * Yes, this library is not thread-safe.
49
 */
50
static unsigned int loglevel;
51
/* the current version per spec block */
52
static int cur_ver = 0;
53
static BITCODE_BL rcount1 = 0, rcount2 = 0;
54
55
#ifdef DWG_ABORT
56
static unsigned int errors = 0;
57
#  ifndef DWG_ABORT_LIMIT
58
#    define DWG_ABORT_LIMIT 200
59
#  endif
60
#endif
61
62
#include "dynapi.h"
63
#include "dec_macros.h"
64
#include "decode_r11.h"
65
66
// need spec.h for the LOG_FLAG_TABLE*
67
#define ACTION decode
68
#include "spec.h"
69
70
void dwg_set_next_hdl (Dwg_Data *dwg, unsigned long value);
71
72
/*------------------------------------------------------------------------------
73
 * Private functions
74
 */
75
76
static int decode_preR13_section_hdr (const char *restrict name,
77
                                      Dwg_Section_Type_r11 id,
78
                                      Bit_Chain *restrict dat,
79
                                      Dwg_Data *restrict dwg);
80
static int decode_preR13_section (Dwg_Section_Type_r11 id,
81
                                  Bit_Chain *restrict dat,
82
                                  Dwg_Data *restrict dwg);
83
84
/*----------------------------------------------------------------------------
85
 * Public function definitions
86
 */
87
88
EXPORT Dwg_Object_Ref *
89
dwg_decode_preR13_handleref (Bit_Chain *restrict dat, int size,
90
                             Dwg_Data *restrict dwg)
91
1.17M
{
92
1.17M
  Dwg_Object_Ref *ref = dwg_new_ref (dwg);
93
1.17M
  if (!ref)
94
0
    {
95
0
      LOG_ERROR ("Out of memory");
96
0
      return NULL;
97
0
    }
98
  // dwg->object_ref[dwg->num_object_refs++] = ref;
99
  // ref->handleref.is_global = 1;
100
1.17M
  ref->handleref.size = size;
101
1.17M
  if (size == 2)
102
838k
    ref->r11_idx = (BITCODE_RSd)bit_read_RS (dat);
103
337k
  else
104
337k
    ref->r11_idx = (BITCODE_RCd)bit_read_RC (dat);
105
1.17M
  return ref;
106
1.17M
}
107
108
static int
109
decode_preR13_header_variables (Bit_Chain *dat, Dwg_Data *restrict dwg)
110
371
{
111
371
  Dwg_Header_Variables *_obj = &dwg->header_vars;
112
371
  Dwg_Object *obj = NULL;
113
371
  Bit_Chain *hdl_dat = dat;
114
371
  int error = 0;
115
116
  // clang-format off
117
371
  #include "header_variables_r11.spec"
118
  // clang-format on
119
120
1
  return error;
121
6.31k
}
122
123
// We put the 5 tables into sections.
124
// number is num_entries in the table. >=r13 it is the id.
125
static int
126
decode_preR13_section_hdr (const char *restrict name, Dwg_Section_Type_r11 id,
127
                           Bit_Chain *restrict dat, Dwg_Data *restrict dwg)
128
2.06k
{
129
  // int error = 0;
130
2.06k
  Dwg_Section *tbl = &dwg->header.section[id];
131
2.06k
  unsigned long end_address;
132
133
2.06k
  if (dat->byte + 10 > dat->size)
134
0
    {
135
0
      LOG_ERROR ("%s.size overflow @%" PRIuSIZE, name, dat->byte)
136
0
      return DWG_ERR_SECTIONNOTFOUND;
137
0
    }
138
2.06k
  tbl->type = (Dwg_Section_Type)id;
139
2.06k
  strncpy (tbl->name, name, sizeof (tbl->name) - 1);
140
2.06k
  tbl->name[sizeof (tbl->name) - 1] = '\0';
141
2.06k
  LOG_TRACE ("ptr table %s_CONTROL [%d]", tbl->name, id);
142
2.06k
  LOG_RPOS;
143
2.06k
  LOG_TRACE ("----------------------\n");
144
2.06k
  tbl->size = (BITCODE_RL)bit_read_RS (dat);
145
2.06k
  LOG_TRACE ("%s_CONTROL.size: " FORMAT_RS " [RS]", tbl->name,
146
2.06k
             (BITCODE_RS)tbl->size);
147
2.06k
  LOG_RPOS;
148
  // RC in r2000, RL in 2004
149
2.06k
  tbl->number = (BITCODE_RLd)((BITCODE_RSd)bit_read_RS (dat));
150
2.06k
  LOG_TRACE ("%s_CONTROL.number: " FORMAT_RS " [RS]", tbl->name,
151
2.06k
             (BITCODE_RS)tbl->number);
152
2.06k
  LOG_RPOS;
153
2.06k
  tbl->flags_r11 = bit_read_RS (dat);
154
2.06k
  LOG_TRACE ("%s_CONTROL.flags_r11: " FORMAT_RSx " [RS]", tbl->name,
155
2.06k
             tbl->flags_r11);
156
2.06k
  LOG_RPOS;
157
2.06k
  tbl->address = bit_read_RL (dat);
158
2.06k
  LOG_TRACE ("%s_CONTROL.address: " FORMAT_RLx " [RL] (%u)", tbl->name,
159
2.06k
             (BITCODE_RL)tbl->address, (unsigned)tbl->address);
160
2.06k
  LOG_RPOS;
161
2.06k
  end_address = (unsigned long)(tbl->address + (tbl->number * tbl->size));
162
2.06k
  LOG_TRACE ("ptr table end: 0x%lx (%lu)\n\n", end_address, end_address);
163
164
2.06k
  switch (id)
165
2.06k
    {
166
371
    case SECTION_BLOCK:
167
371
      {
168
371
        Dwg_Object *obj = dwg_get_first_object (dwg, DWG_TYPE_BLOCK_CONTROL);
169
371
        if (obj)
170
371
          {
171
371
            Dwg_Object_BLOCK_CONTROL *_obj
172
371
                = obj->tio.object->tio.BLOCK_CONTROL;
173
371
            obj->size = tbl->size;
174
371
            obj->address = tbl->address;
175
371
            _obj->flags_r11 = tbl->flags_r11;
176
            //  we cannot set _obj->num_entries, as we add BLOCK's via
177
            //  add_BLOCK_HEADER
178
371
            dwg->block_control = *_obj;
179
371
          }
180
371
      }
181
371
      break;
182
183
0
#define CASE_TBL(TBL)                                                         \
184
1.69k
  case SECTION_##TBL:                                                         \
185
1.69k
    {                                                                         \
186
1.69k
      Dwg_Object *obj = dwg_get_first_object (dwg, DWG_TYPE_##TBL##_CONTROL); \
187
1.69k
      if (obj)                                                                \
188
1.69k
        {                                                                     \
189
1.64k
          Dwg_Object_##TBL##_CONTROL *_obj                                    \
190
1.64k
              = obj->tio.object->tio.TBL##_CONTROL;                           \
191
1.64k
          obj->size = tbl->size;                                              \
192
1.64k
          obj->address = tbl->address;                                        \
193
1.64k
          _obj->flags_r11 = tbl->flags_r11;                                   \
194
1.64k
        }                                                                     \
195
1.69k
    }                                                                         \
196
1.69k
    break
197
198
371
      CASE_TBL (LAYER);
199
371
      CASE_TBL (STYLE);
200
371
      CASE_TBL (LTYPE);
201
371
      CASE_TBL (VIEW);
202
53
      CASE_TBL (UCS); // since r10
203
53
      CASE_TBL (VPORT);
204
53
      CASE_TBL (DIMSTYLE);
205
53
      CASE_TBL (APPID); // since r11
206
1
      CASE_TBL (VX);
207
0
    default:
208
0
      LOG_ERROR ("Illegal section id %d", id);
209
2.06k
    }
210
2.06k
  if (tbl->number > 0 && tbl->size < 33)
211
108
    {
212
108
      LOG_ERROR ("Wrong %s.number " FORMAT_RLd " or size %u", tbl->name,
213
108
                 tbl->number, (unsigned)tbl->size)
214
108
      return 1; // DWG_ERR_SECTIONNOTFOUND;
215
108
    }
216
1.96k
  if (tbl->number > 0
217
789
      && (tbl->address + (tbl->number * tbl->size) > dat->size))
218
679
    {
219
679
      LOG_ERROR ("%s.size overflow %" PRIuSIZE " > %" PRIuSIZE, tbl->name,
220
679
                 (size_t)(tbl->address + (tbl->number * tbl->size)),
221
679
                 dat->size);
222
      // VPORT.size bug in DWG, ignore it.
223
679
      return id == SECTION_VPORT ? 0 : 1;
224
679
    }
225
1.28k
  return 0;
226
1.96k
}
227
228
GCC30_DIAG_IGNORE (-Wformat-nonliteral)
229
// TABLES really
230
static int
231
decode_preR13_section (Dwg_Section_Type_r11 id, Bit_Chain *restrict dat,
232
                       Dwg_Data *restrict dwg)
233
418
{
234
418
  Dwg_Section *tbl = &dwg->header.section[id];
235
  // Bit_Chain *hdl_dat = dat;
236
418
  Dwg_Object *obj;
237
418
  int error = 0;
238
418
  BITCODE_RLd i;
239
  // BITCODE_RL vcount;
240
418
  BITCODE_RL num = dwg->num_objects;
241
418
  size_t pos = tbl->address;
242
418
  size_t oldpos;
243
418
  size_t real_start = pos;
244
  // BITCODE_TF name;
245
  // BITCODE_RSd used = -1;
246
  // BITCODE_RC flag;
247
248
418
  LOG_TRACE ("\ncontents table %-8s [%2d]: size:%-4u num:%-3ld (" FORMAT_RLL
249
418
             "-" FORMAT_RLL ")\n\n",
250
418
             tbl->name, id, tbl->size, (long)tbl->number, tbl->address,
251
418
             tbl->address + (tbl->number * tbl->size))
252
253
  // with sentinel in case of R11
254
418
  SINCE (R_11)
255
0
  {
256
0
    real_start -= 16; // the sentinel size
257
0
  }
258
259
  // report unknown data before table
260
418
  if (tbl->address && dat->byte != real_start)
261
116
    {
262
116
      LOG_WARN ("\n@0x%zx => start 0x%zx", dat->byte, real_start);
263
116
      if (dat->byte < real_start)
264
58
        {
265
58
          UNKNOWN_UNTIL (real_start);
266
58
        }
267
116
    }
268
269
418
  SINCE (R_11)
270
0
  {
271
0
#define DECODE_PRER13_SENTINEL(ID)                                            \
272
0
  error |= decode_preR13_sentinel (ID, #ID, dat, dwg);                        \
273
0
  if (error >= DWG_ERR_SECTIONNOTFOUND)                                       \
274
0
  return error
275
276
0
    switch (id)
277
0
      {
278
0
#define CASE_SENTINEL_BEGIN(id)                                               \
279
0
  case SECTION_##id:                                                          \
280
0
    DECODE_PRER13_SENTINEL (DWG_SENTINEL_R11_##id##_BEGIN);                   \
281
0
    break
282
283
0
        CASE_SENTINEL_BEGIN (BLOCK);
284
0
        CASE_SENTINEL_BEGIN (LAYER);
285
0
        CASE_SENTINEL_BEGIN (STYLE);
286
0
        CASE_SENTINEL_BEGIN (LTYPE);
287
0
        CASE_SENTINEL_BEGIN (VIEW);
288
0
        CASE_SENTINEL_BEGIN (UCS);
289
0
        CASE_SENTINEL_BEGIN (VPORT);
290
0
        CASE_SENTINEL_BEGIN (APPID);
291
0
        CASE_SENTINEL_BEGIN (DIMSTYLE);
292
0
        CASE_SENTINEL_BEGIN (VX);
293
0
#undef CASE_SENTINEL_BEGIN
294
295
0
      default:
296
0
        LOG_ERROR ("Internal error: Invalid section id %d", (int)id);
297
0
        return DWG_ERR_INTERNALERROR;
298
0
      }
299
0
  }
300
301
418
  oldpos = dat->byte;
302
418
  if (tbl->address)
303
116
    dat->byte = tbl->address;
304
418
  dat->bit = 0;
305
418
  if ((size_t)(tbl->number * tbl->size) > dat->size - dat->byte)
306
0
    {
307
0
      LOG_ERROR ("Overlarge table num_entries %ld or size %ld for %-8s [%2d]",
308
0
                 (long)tbl->number, (long)tbl->size, tbl->name, id);
309
0
      dat->byte = oldpos;
310
0
      return DWG_ERR_INVALIDDWG;
311
0
    }
312
418
  tbl->objid_r11 = num;
313
418
  if (dwg->num_alloced_objects < dwg->num_objects + tbl->number)
314
55
    {
315
55
      dwg->num_alloced_objects = dwg->num_objects + tbl->number;
316
55
      if (dwg->num_alloced_objects > dwg->num_objects + MAX_NUM)
317
1
        {
318
1
          LOG_ERROR ("Invalid num_alloced_objects " FORMAT_BL,
319
1
                     dwg->num_alloced_objects);
320
1
          return DWG_ERR_INVALIDDWG;
321
1
        }
322
54
      dwg->object = (Dwg_Object *)realloc (
323
54
          dwg->object, dwg->num_alloced_objects * sizeof (Dwg_Object));
324
54
      dwg->dirty_refs = 1;
325
54
    }
326
327
417
#define SET_CONTROL(token)                                                    \
328
417
  Dwg_Object *ctrl;                                                           \
329
417
  Dwg_Object_##token##_CONTROL *_ctrl = NULL;                                 \
330
417
  ctrl = dwg_get_first_object (dwg, DWG_TYPE_##token##_CONTROL);              \
331
417
  if (ctrl)                                                                   \
332
417
    {                                                                         \
333
413
      _ctrl = ctrl->tio.object->tio.token##_CONTROL;                          \
334
413
      ctrl->size = tbl->size;                                                 \
335
413
      if (tbl->number > _ctrl->num_entries)                                   \
336
413
        {                                                                     \
337
161
          if (_ctrl->entries)                                                 \
338
161
            {                                                                 \
339
109
              _ctrl->entries = (BITCODE_H *)realloc (                         \
340
109
                  _ctrl->entries, tbl->number * sizeof (BITCODE_H));          \
341
109
              memset (&_ctrl->entries[_ctrl->num_entries], 0,                 \
342
109
                      (tbl->number - _ctrl->num_entries)                      \
343
109
                          * sizeof (BITCODE_H));                              \
344
109
            }                                                                 \
345
161
          else                                                                \
346
161
            _ctrl->entries                                                    \
347
52
                = (BITCODE_H *)calloc (tbl->number, sizeof (BITCODE_H));      \
348
161
          _ctrl->num_entries = tbl->number;                                   \
349
161
          LOG_TRACE (#token "_CONTROL.num_entries = %u\n", tbl->number);      \
350
161
        }                                                                     \
351
413
    }
352
353
417
#define NEW_OBJECT                                                            \
354
29.7k
  dwg_add_object (dwg);                                                       \
355
29.7k
  if (dat->byte > dat->size)                                                  \
356
29.7k
    return DWG_ERR_INVALIDDWG;                                                \
357
29.7k
  obj = &dwg->object[num++];                                                  \
358
29.7k
  obj->address = dat->byte;                                                   \
359
29.7k
  obj->size = tbl->size;
360
361
417
#define ADD_CTRL_ENTRY                                                        \
362
29.7k
  if (_ctrl)                                                                  \
363
29.7k
    {                                                                         \
364
29.7k
      BITCODE_H ref;                                                          \
365
29.7k
      if (!obj->handle.value)                                                 \
366
29.7k
        obj->handle.value = dwg_next_handseed (dwg);                          \
367
29.7k
      ref = _ctrl->entries[i]                                                 \
368
29.7k
          = dwg_add_handleref (dwg, 2, obj->handle.value, obj);               \
369
29.7k
      ref->r11_idx = i;                                                       \
370
29.7k
      LOG_TRACE ("%s.entries[%u] = " FORMAT_REF " [H 0]\n", ctrl->name, i,    \
371
29.7k
                 ARGS_REF (ref));                                             \
372
29.7k
    }                                                                         \
373
29.7k
  else                                                                        \
374
29.7k
    return error | DWG_ERR_INVALIDDWG
375
376
417
#define CHK_ENDPOS                                                            \
377
29.7k
  SINCE (R_11)                                                                \
378
29.7k
  {                                                                           \
379
0
    if (!bit_check_CRC (dat, obj->address, 0xC0C1))                           \
380
0
      error |= DWG_ERR_WRONGCRC;                                              \
381
0
  }                                                                           \
382
29.7k
  pos = tbl->address + (long)((i + 1) * tbl->size);                           \
383
29.7k
  if (pos != dat->byte)                                                       \
384
29.7k
    {                                                                         \
385
29.6k
      LOG_ERROR ("offset %ld", (long)(pos - dat->byte));                      \
386
29.6k
      if (pos > dat->byte)                                                    \
387
29.6k
        {                                                                     \
388
8.07k
          BITCODE_RL offset = (BITCODE_RL)(pos - dat->byte);                  \
389
8.07k
          obj->num_unknown_rest = 8 * offset;                                 \
390
8.07k
          obj->unknown_rest = (BITCODE_TF)calloc (offset + 1, 1);             \
391
8.07k
          if (obj->unknown_rest)                                              \
392
8.07k
            {                                                                 \
393
8.07k
              memcpy (obj->unknown_rest, &dat->chain[dat->byte], offset);     \
394
8.07k
              LOG_TRACE_TF (obj->unknown_rest, offset);                       \
395
8.07k
            }                                                                 \
396
8.07k
          else                                                                \
397
8.07k
            {                                                                 \
398
0
              LOG_ERROR ("Out of memory");                                    \
399
0
              obj->num_unknown_rest = 0;                                      \
400
0
            }                                                                 \
401
8.07k
        }                                                                     \
402
      /* In the table header the size OR number can be wrong. */              \
403
      /* Here we catch the wrong number. */                                   \
404
29.6k
      if (tbl->number > 0 && tbl->size < 33)                                  \
405
29.6k
        return DWG_ERR_SECTIONNOTFOUND;                                       \
406
29.6k
    }                                                                         \
407
29.7k
  LOG_TRACE ("\n")                                                            \
408
29.7k
  dat->byte = pos
409
410
417
  switch (id)
411
417
    {
412
63
    case SECTION_BLOCK:
413
63
      {
414
63
        SET_CONTROL (BLOCK);
415
73
        for (i = 0; i < tbl->number; i++)
416
12
          {
417
12
            NEW_OBJECT;
418
10
            error |= dwg_decode_BLOCK_HEADER (dat, obj);
419
            // PUSH_HV (_hdr, num_owned, entities, ref);
420
10
            ADD_CTRL_ENTRY;
421
20
            CHK_ENDPOS;
422
20
          }
423
63
      }
424
61
      break;
425
426
61
    case SECTION_LAYER:
427
61
      {
428
61
        SET_CONTROL (LAYER);
429
61
        for (i = 0; i < tbl->number; i++)
430
0
          {
431
0
            NEW_OBJECT;
432
0
            error |= dwg_decode_LAYER (dat, obj);
433
0
            ADD_CTRL_ENTRY;
434
0
            CHK_ENDPOS;
435
0
          }
436
61
      }
437
61
      break;
438
439
    // was a text STYLE table, became a STYLE object
440
61
    case SECTION_STYLE:
441
61
      {
442
61
        SET_CONTROL (STYLE);
443
293
        for (i = 0; i < tbl->number; i++)
444
233
          {
445
233
            NEW_OBJECT;
446
232
            error |= dwg_decode_STYLE (dat, obj);
447
232
            ADD_CTRL_ENTRY;
448
464
            CHK_ENDPOS;
449
464
          }
450
61
      }
451
60
      break;
452
453
60
    case SECTION_LTYPE:
454
59
      {
455
59
        SET_CONTROL (LTYPE);
456
59
        for (i = 0; i < tbl->number; i++)
457
0
          {
458
0
            NEW_OBJECT;
459
0
            error |= dwg_decode_LTYPE (dat, obj);
460
0
            ADD_CTRL_ENTRY;
461
0
            if (strEQc (tbl->name, "CONTINUOUS"))
462
0
              dwg->header_vars.LTYPE_CONTINUOUS = _ctrl->entries[i];
463
0
            CHK_ENDPOS;
464
0
          }
465
59
      }
466
59
      break;
467
468
59
    case SECTION_VIEW:
469
59
      {
470
59
        SET_CONTROL (VIEW);
471
59
        for (i = 0; i < tbl->number; i++)
472
0
          {
473
0
            NEW_OBJECT;
474
0
            error |= dwg_decode_VIEW (dat, obj);
475
0
            ADD_CTRL_ENTRY;
476
0
            CHK_ENDPOS;
477
0
          }
478
59
      }
479
59
      break;
480
481
    // SINCE R_11
482
59
    case SECTION_UCS:
483
54
      {
484
54
        SET_CONTROL (UCS);
485
29.5k
        for (i = 0; i < tbl->number; i++)
486
29.4k
          {
487
29.4k
            NEW_OBJECT;
488
29.4k
            error |= dwg_decode_UCS (dat, obj);
489
29.4k
            ADD_CTRL_ENTRY;
490
58.9k
            CHK_ENDPOS;
491
58.9k
          }
492
54
      }
493
54
      break;
494
495
    // SINCE R_11
496
54
    case SECTION_VPORT:
497
54
      {
498
54
        SET_CONTROL (VPORT);
499
54
        for (i = 0; i < tbl->number; i++)
500
52
          {
501
52
            NEW_OBJECT;
502
0
            error |= dwg_decode_VPORT (dat, obj);
503
0
            ADD_CTRL_ENTRY;
504
0
            CHK_ENDPOS;
505
0
          }
506
54
      }
507
2
      break;
508
509
    // SINCE R_11
510
2
    case SECTION_APPID:
511
2
      {
512
2
        SET_CONTROL (APPID);
513
2
        for (i = 0; i < tbl->number; i++)
514
0
          {
515
0
            NEW_OBJECT;
516
0
            error |= dwg_decode_APPID (dat, obj);
517
0
            ADD_CTRL_ENTRY;
518
0
            CHK_ENDPOS;
519
0
          }
520
2
      }
521
2
      break;
522
523
    // SINCE R_11
524
2
    case SECTION_DIMSTYLE:
525
2
      {
526
2
        SET_CONTROL (DIMSTYLE);
527
2
        for (i = 0; i < tbl->number; i++)
528
0
          {
529
0
            NEW_OBJECT;
530
0
            error |= dwg_decode_DIMSTYLE (dat, obj);
531
0
            ADD_CTRL_ENTRY;
532
0
            CHK_ENDPOS;
533
0
          }
534
2
      }
535
2
      break;
536
537
    // SINCE R_11
538
2
    case SECTION_VX:
539
2
      {
540
2
        SET_CONTROL (VX);
541
2
        for (i = 0; i < tbl->number; i++)
542
0
          {
543
0
            NEW_OBJECT;
544
0
            error |= dwg_decode_VX_TABLE_RECORD (dat, obj);
545
0
            ADD_CTRL_ENTRY;
546
0
            CHK_ENDPOS;
547
0
          }
548
2
      }
549
2
      break;
550
551
2
    case SECTION_HEADER_R11:
552
0
    default:
553
0
      LOG_ERROR ("Invalid table id %d", id);
554
0
      tbl->number = 0;
555
0
      break;
556
417
    }
557
558
362
  if (tbl->address && tbl->number && tbl->size)
559
56
    dat->byte = tbl->address + (tbl->number * tbl->size);
560
306
  else
561
306
    dat->byte = oldpos;
562
563
362
  SINCE (R_11)
564
0
  {
565
0
    switch (id)
566
0
      {
567
0
#define CASE_SENTINEL_END(id)                                                 \
568
0
  case SECTION_##id:                                                          \
569
0
    DECODE_PRER13_SENTINEL (DWG_SENTINEL_R11_##id##_END);                     \
570
0
    break
571
572
0
        CASE_SENTINEL_END (BLOCK);
573
0
        CASE_SENTINEL_END (LAYER);
574
0
        CASE_SENTINEL_END (STYLE);
575
0
        CASE_SENTINEL_END (LTYPE);
576
0
        CASE_SENTINEL_END (VIEW);
577
0
        CASE_SENTINEL_END (UCS);
578
0
        CASE_SENTINEL_END (VPORT);
579
0
        CASE_SENTINEL_END (APPID);
580
0
        CASE_SENTINEL_END (DIMSTYLE);
581
0
        CASE_SENTINEL_END (VX);
582
0
      default:
583
0
        LOG_ERROR ("Internal error: Invalid section id %d", (int)id);
584
0
        return DWG_ERR_INTERNALERROR;
585
0
      }
586
0
  }
587
362
#undef DECODE_PRER13_SENTINEL
588
362
#undef CASE_SENTINEL_END
589
590
362
  return error;
591
362
}
592
593
EXPORT int
594
decode_entity_preR13 (Bit_Chain *restrict dat, Dwg_Object *restrict obj,
595
                      Dwg_Object_Entity *_ent)
596
471k
{
597
471k
  Dwg_Object_Entity *_obj = _ent;
598
471k
  const bool is_block = obj->address >= 0x40000000;
599
471k
  Bit_Chain *hdl_dat = NULL, *str_dat = NULL;
600
471k
  Dwg_Data *dwg = _ent->dwg;
601
471k
  int error = 0; // errors only with H or CMC. r11 has none of these
602
603
471k
  obj->bitsize_pos = bit_position (dat);
604
471k
  obj->address
605
471k
      = dat->byte - 1; // already read the type. size includes the type
606
471k
  LOG_INFO ("===========================\n"
607
471k
            "Entity number: %d, Type: %d, Addr: %zx\n",
608
471k
            obj->index, obj->type, obj->address);
609
471k
  _obj->entmode = is_block ? 3 : 2; // ent or block
610
611
471k
#include "common_entity_data.spec"
612
613
441k
  if (!obj->handle.value) // can be set via FLAG_R11_HAS_HANDLING also
614
436k
    {
615
436k
      obj->handle.value = dwg_next_handle (dwg);
616
436k
      dwg_add_handle (&obj->handle, 0, obj->handle.value, obj);
617
436k
      LOG_TRACE ("=> handle: (0.%d." FORMAT_HV ")\n", obj->handle.size,
618
436k
                 obj->handle.value);
619
436k
    }
620
441k
  obj->common_size = bit_position (dat) - obj->bitsize_pos;
621
441k
  return error;
622
882k
}
623
624
AFL_GCC_TOOBIG
625
EXPORT int
626
decode_preR13 (Bit_Chain *restrict dat, Dwg_Data *restrict dwg)
627
371
{
628
371
  BITCODE_RL num_entities;
629
371
  BITCODE_RL blocks_start = 0, blocks_end = 0, blocks_size = 0;
630
371
  BITCODE_RL extras_start = 0, extras_end = 0, extras_size = 0;
631
  // BITCODE_RS rs2;
632
371
  Dwg_Object *obj = NULL;
633
371
  int error = 0;
634
  // Bit_Chain dat_save = *dat;
635
636
371
  loglevel = dat->opts & DWG_OPTS_LOGLEVEL;
637
371
  {
638
371
    int i;
639
371
    Dwg_Header *_obj = (Dwg_Header *)&dwg->header;
640
    // Bit_Chain *hdl_dat = dat;
641
371
    BITCODE_BL vcount;
642
643
    // clang-format off
644
371
    #include "header.spec"
645
    // clang-format on
646
371
  }
647
371
  LOG_TRACE ("@0x%zx\n", dat->byte); // 0x14
648
371
  SINCE (R_2_0b)
649
371
  {
650
    // Block entities
651
371
    blocks_start = dwg->header.blocks_start;
652
371
    blocks_size = dwg->header.blocks_size;
653
371
    if (blocks_size > 0xffffff)
654
247
      {
655
247
        blocks_size &= 0xffffff;
656
247
        LOG_TRACE ("blocks_size => " FORMAT_RLx "\n", blocks_size);
657
247
      }
658
371
    blocks_end = blocks_start + blocks_size;
659
    // Extra entities
660
371
    extras_start = dwg->header.extras_start;
661
371
    extras_size = dwg->header.extras_size;
662
371
    if (extras_size > 0xffffff)
663
284
      {
664
284
        extras_size &= 0xffffff;
665
284
        LOG_TRACE ("extras_size => " FORMAT_RLx "\n", extras_size);
666
284
      }
667
371
    extras_end = extras_start + extras_size;
668
371
  }
669
670
  // setup all the new control objects
671
371
  error |= dwg_add_Document (dwg, 0);
672
371
  if (error >= DWG_ERR_CRITICAL)
673
0
    return error;
674
675
371
  SINCE (R_2_0b)
676
371
  {
677
371
    dwg->header.section[0].number = 0;
678
371
    dwg->header.section[0].type = (Dwg_Section_Type)SECTION_HEADER_R11;
679
371
    strcpy (dwg->header.section[0].name, "HEADER");
680
681
    // The 5 tables (num_sections always 5): 3 RS + 1 RL address
682
371
    LOG_INFO ("==========================================\n")
683
    // dat_save = *dat;
684
371
    error |= decode_preR13_section_hdr ("BLOCK", SECTION_BLOCK, dat, dwg);
685
371
    if (error >= DWG_ERR_CRITICAL)
686
0
      return error;
687
371
    error |= decode_preR13_section_hdr ("LAYER", SECTION_LAYER, dat, dwg);
688
371
    if (error >= DWG_ERR_CRITICAL)
689
0
      return error;
690
371
    error |= decode_preR13_section_hdr ("STYLE", SECTION_STYLE, dat, dwg);
691
371
    if (error >= DWG_ERR_CRITICAL)
692
0
      return error;
693
371
    error |= decode_preR13_section_hdr ("LTYPE", SECTION_LTYPE, dat, dwg);
694
371
    if (error >= DWG_ERR_CRITICAL)
695
0
      return error;
696
371
    error |= decode_preR13_section_hdr ("VIEW", SECTION_VIEW, dat, dwg);
697
371
    if (error >= DWG_ERR_CRITICAL)
698
0
      return error;
699
371
  }
700
371
  LOG_TRACE ("@0x%zx\n", dat->byte); // 0x5e
701
371
  if (dat->size < 0x1f0)             // AC1.50 0x1f9 74 vars
702
0
    {
703
0
      LOG_ERROR ("DWG too small %" PRIuSIZE, (size_t)dat->size)
704
0
      return DWG_ERR_INVALIDDWG;
705
0
    }
706
707
371
  LOG_TRACE ("==========================================\n")
708
371
  error |= decode_preR13_header_variables (dat, dwg);
709
371
  LOG_TRACE ("@0x%zx\n", dat->byte);
710
371
  if (error >= DWG_ERR_CRITICAL)
711
0
    return error;
712
371
  if (dat->byte + 2 >= dat->size)
713
0
    {
714
0
      LOG_ERROR ("post HEADER overflow")
715
0
      return error | DWG_ERR_CRITICAL;
716
0
    }
717
371
  SINCE (R_11)
718
10
  {
719
    // crc16 + DWG_SENTINEL_R11_ENTITIES_BEGIN
720
10
    BITCODE_RS crc, crcc;
721
10
    crcc = bit_calc_CRC (0xC0C1, &dat->chain[0], dat->byte); // from 0 to now
722
10
    crc = bit_read_RS (dat);
723
10
    LOG_TRACE ("crc: %04X [RSx] from 0-0x%zx\n", crc, dat->byte - 2);
724
10
    if (crc != crcc)
725
10
      {
726
10
        LOG_ERROR ("Header CRC mismatch %04X <=> %04X", crc, crcc);
727
10
        error |= DWG_ERR_WRONGCRC;
728
10
      }
729
10
  }
730
731
371
  PRE (R_10)
732
171
  {
733
171
    num_entities = dwg->header_vars.numentities;
734
171
  }
735
200
  LATER_VERSIONS
736
200
  {
737
200
    num_entities = 0;
738
200
  }
739
371
  PRE (R_2_0b)
740
0
  {
741
0
    dwg->header.entities_start = dat->byte & 0xFFFFFFFF;
742
0
    dwg->header.entities_end = dwg->header_vars.dwg_size;
743
0
  }
744
745
  // entities
746
371
  error |= decode_preR13_entities (
747
371
      dwg->header.entities_start, dwg->header.entities_end, num_entities,
748
371
      dwg->header.entities_end - dwg->header.entities_start, dat, dwg,
749
371
      ENTITIES_SECTION_INDEX);
750
371
  if (error >= DWG_ERR_CRITICAL)
751
308
    return error;
752
753
63
  PRE (R_2_0b)
754
0
  {
755
    // this has usually some slack at the end.
756
0
    return error;
757
0
  }
758
759
63
  error |= decode_preR13_section (SECTION_BLOCK, dat, dwg);
760
63
  if (error >= DWG_ERR_CRITICAL)
761
2
    return error;
762
61
  error |= decode_preR13_section (SECTION_LAYER, dat, dwg);
763
61
  if (error >= DWG_ERR_CRITICAL)
764
0
    return error;
765
61
  error |= decode_preR13_section (SECTION_STYLE, dat, dwg);
766
61
  if (error >= DWG_ERR_CRITICAL)
767
1
    return error;
768
60
  error |= decode_preR13_section (SECTION_LTYPE, dat, dwg);
769
60
  if (error >= DWG_ERR_CRITICAL)
770
1
    return error;
771
59
  error |= decode_preR13_section (SECTION_VIEW, dat, dwg);
772
59
  if (error >= DWG_ERR_CRITICAL)
773
0
    return error;
774
59
  if (dwg->header.num_sections >= SECTION_VPORT) // r10
775
54
    {
776
54
      error |= decode_preR13_section (SECTION_UCS, dat, dwg);
777
54
      if (error >= DWG_ERR_CRITICAL)
778
0
        return error;
779
54
      error |= decode_preR13_section (SECTION_VPORT, dat, dwg);
780
54
      if (error >= DWG_ERR_CRITICAL)
781
52
        return error;
782
54
    }
783
7
  if (dwg->header.num_sections >= SECTION_APPID) // r10
784
2
    {
785
2
      error |= decode_preR13_section (SECTION_APPID, dat, dwg);
786
2
      if (error >= DWG_ERR_CRITICAL)
787
0
        return error;
788
2
    }
789
7
  if (dwg->header.num_sections >= SECTION_VX) // r11
790
2
    {
791
2
      error |= decode_preR13_section (SECTION_DIMSTYLE, dat, dwg);
792
2
      if (error >= DWG_ERR_CRITICAL)
793
0
        return error;
794
2
      error |= decode_preR13_section (SECTION_VX, dat, dwg);
795
2
      if (error >= DWG_ERR_CRITICAL)
796
0
        return error;
797
2
    }
798
799
  // block entities
800
7
  error |= decode_preR13_entities (blocks_start, blocks_end, 0, blocks_size,
801
7
                                   dat, dwg, BLOCKS_SECTION_INDEX);
802
7
  if (error >= DWG_ERR_CRITICAL)
803
7
    return error;
804
805
  // extra entities
806
0
  error |= decode_preR13_entities (extras_start, extras_end, 0, extras_size,
807
0
                                   dat, dwg, EXTRAS_SECTION_INDEX);
808
0
  if (error >= DWG_ERR_CRITICAL)
809
0
    return error;
810
811
  // aux header
812
0
  SINCE (R_11)
813
0
  {
814
0
    error |= decode_r11_auxheader (dat, dwg);
815
0
    if (error >= DWG_ERR_CRITICAL)
816
0
      return error;
817
0
  }
818
819
0
  if (dat->byte < dat->size)
820
0
    {
821
0
      size_t len = dat->size - dat->byte;
822
0
      BITCODE_TF unknown = bit_read_TF (dat, len);
823
0
      LOG_TRACE ("unknown (%" PRIuSIZE "):", len);
824
0
      LOG_TRACE_TF (unknown, len);
825
0
      free (unknown);
826
0
    }
827
828
0
  if (dwg->dirty_refs)
829
0
    dwg_resolve_objectrefs_silent (dwg);
830
0
  return 0;
831
0
}
832
AFL_GCC_POP
833
834
#undef IS_DECODER