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