Skip to content

Commit

Permalink
add template and objfreespace sections
Browse files Browse the repository at this point in the history
template is the 2000 MEASUREMENT section (maybe rename the old one),
  • Loading branch information
rurban committed Jan 12, 2020
1 parent aa8990c commit 261cb96
Show file tree
Hide file tree
Showing 8 changed files with 288 additions and 8 deletions.
23 changes: 23 additions & 0 deletions include/dwg.h
Original file line number Diff line number Diff line change
Expand Up @@ -5840,6 +5840,29 @@ typedef struct _dwg_struct
char *unknown_bits;
} revhistory;

struct Dwg_ObjFreeSpace
{
BITCODE_RLL zero;
BITCODE_RLL num_handles;
BITCODE_TIMERLL TDUPDATE;
BITCODE_RL objects_address;
BITCODE_RC num_nums; // RLL (uint64_t) or uint128_t
BITCODE_RLL max32;
BITCODE_RLL max64;
BITCODE_RLL maxtbl;
BITCODE_RLL maxrl;
BITCODE_RLL max32_hi;
BITCODE_RLL max64_hi;
BITCODE_RLL maxtbl_hi;
BITCODE_RLL maxrl_hi;
} objfreespace;

struct Dwg_Template
{
BITCODE_T16 desc;
BITCODE_RS MEASUREMENT;
} template;

struct _dwg_second_header {
BITCODE_RL size;
BITCODE_RL address;
Expand Down
2 changes: 2 additions & 0 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ EXTRA_HEADERS = \
filedeplist.spec \
security.spec \
vbaproject.spec \
template.spec \
objfreespace.spec \
classes.inc \
objects.inc \
spec.h \
Expand Down
1 change: 1 addition & 0 deletions src/dec_macros.h
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,7 @@
LOG_TRACE (#nam ": [TFFx %d " #dxf "]\n ", (int)len); \
LOG_TRACE_TF (FIELD_VALUE (nam), (int)len); \
}
#define FIELD_T16(nam, dxf) FIELDG (nam, T16, dxf)
#define FIELD_TU16(nam, dxf) \
{ \
_obj->nam = bit_read_TU16 (dat); \
Expand Down
107 changes: 101 additions & 6 deletions src/decode.c
Original file line number Diff line number Diff line change
Expand Up @@ -2275,7 +2275,9 @@ read_2004_compressed_section (Bit_Chain *dat, Dwg_Data *restrict dwg,
sec_dat->chain = NULL; // fixes double-free
if (!info)
{
if (type < SECTION_REVHISTORY)
if (type < SECTION_REVHISTORY
&& type != SECTION_TEMPLATE
&& type != SECTION_OBJFREESPACE)
{
LOG_WARN ("Failed to find section_info[%u] with type %d", i, type)
}
Expand All @@ -2294,6 +2296,8 @@ read_2004_compressed_section (Bit_Chain *dat, Dwg_Data *restrict dwg,
}

max_decomp_size = info->num_sections * info->max_decomp_size;
if (info->num_sections == 0)
return 0;
if (max_decomp_size == 0 || max_decomp_size > 0x2f000000) // 790Mb
{
LOG_ERROR ("Invalid section %s count or max decompression size. "
Expand Down Expand Up @@ -2392,7 +2396,7 @@ read_2004_compressed_section (Bit_Chain *dat, Dwg_Data *restrict dwg,
LOG_ERROR ("Some section size out of bounds")
sec_dat->chain = NULL;
free (decomp);
return type > SECTION_REVHISTORY ? DWG_ERR_INVALIDDWG
return type < SECTION_REVHISTORY ? DWG_ERR_INVALIDDWG
: DWG_ERR_VALUEOUTOFBOUNDS;
}
memcpy (&decomp[i * info->size],
Expand Down Expand Up @@ -2940,7 +2944,7 @@ read_2004_section_vbaproject (Bit_Chain *restrict dat, Dwg_Data *restrict dwg)
old_dat = *dat;
dat = &sec_dat; // restrict in size

DEBUG_HERE
//DEBUG_HERE
_obj->size = dat->size;
_obj->unknown_bits = bit_read_TF (dat, _obj->size);
LOG_TRACE_TF (_obj->unknown_bits, _obj->size)
Expand Down Expand Up @@ -2972,7 +2976,7 @@ read_2004_section_appinfohistory (Bit_Chain *restrict dat, Dwg_Data *restrict dw
old_dat = *dat;
dat = &sec_dat; // restrict in size

DEBUG_HERE
//DEBUG_HERE
_obj->size = dat->size;
_obj->unknown_bits = bit_read_TF (dat, _obj->size);
LOG_TRACE_TF (_obj->unknown_bits, _obj->size)
Expand All @@ -2984,7 +2988,7 @@ read_2004_section_appinfohistory (Bit_Chain *restrict dat, Dwg_Data *restrict dw
return error;
}

/* RevHistory Section
/* Unknown RevHistory Section
*/
static int
read_2004_section_revhistory (Bit_Chain *restrict dat, Dwg_Data *restrict dwg)
Expand All @@ -3004,7 +3008,7 @@ read_2004_section_revhistory (Bit_Chain *restrict dat, Dwg_Data *restrict dwg)
old_dat = *dat;
dat = &sec_dat; // restrict in size

DEBUG_HERE
//DEBUG_HERE
_obj->size = dat->size;
_obj->unknown_bits = bit_read_TF (dat, _obj->size);
LOG_TRACE_TF (_obj->unknown_bits, _obj->size)
Expand All @@ -3016,6 +3020,95 @@ read_2004_section_revhistory (Bit_Chain *restrict dat, Dwg_Data *restrict dwg)
return error;
}

/* ObjFreeSpace Section
*/
static int
read_2004_section_objfreespace (Bit_Chain *restrict dat, Dwg_Data *restrict dwg)
{
Bit_Chain old_dat, sec_dat = { 0 };
int error;
struct Dwg_ObjFreeSpace *_obj = &dwg->objfreespace;

// compressed
error = read_2004_compressed_section (dat, dwg, &sec_dat, SECTION_OBJFREESPACE);
if (error >= DWG_ERR_CRITICAL || !sec_dat.chain)
{
LOG_INFO ("%s section not found\n", "ObjFreeSpace");
return 0;
}

LOG_TRACE ("ObjFreeSpace\n-------------------\n")
old_dat = *dat;
dat = &sec_dat; // restrict in size

// clang-format off
#include "objfreespace.spec"
// clang-format on

LOG_TRACE ("\n")
if (sec_dat.chain)
free (sec_dat.chain);
*dat = old_dat; // unrestrict
return error;
}

// may return OUTOFBOUNDS
static int
template_private (Bit_Chain *restrict dat, Dwg_Data *restrict dwg)
{
Bit_Chain *str_dat = dat;
struct Dwg_Template *_obj = &dwg->template;
Dwg_Object *obj = NULL;
int error = 0;

// clang-format off
#include "template.spec"
// clang-format on

dwg->header_vars.MEASUREMENT = _obj->MEASUREMENT;
LOG_TRACE ("HEADER.MEASUREMENT: " FORMAT_BS " (0 English/1 Metric)\n",
dwg->header_vars.MEASUREMENT)

return error;
}

/* Template Section. Optional r2004, mandatory r2007+
Contains the MEASUREMENT variable (0 = English, 1 = Metric).
*/
static int
read_2004_section_template (Bit_Chain *restrict dat, Dwg_Data *restrict dwg)
{
Bit_Chain old_dat, sec_dat = { 0 };
int error;
// compressed
error = read_2004_compressed_section (dat, dwg, &sec_dat, SECTION_TEMPLATE);
if (error >= DWG_ERR_CRITICAL || !sec_dat.chain)
{
UNTIL (R_2004)
{
LOG_INFO ("%s section not found\n", "Template")
return error;
}
LATER_VERSIONS
{
LOG_ERROR ("%s section not found\n", "Template")
}
return error | DWG_ERR_SECTIONNOTFOUND;
}

LOG_TRACE ("Template\n-------------------\n")
old_dat = *dat;
dat = &sec_dat; // restrict in size

error |= template_private (dat, dwg);

LOG_TRACE ("\n")
if (sec_dat.chain)
free (sec_dat.chain);
*dat = old_dat; // unrestrict
return error;
}

static int
read_2004_section_preview (Bit_Chain *restrict dat, Dwg_Data *restrict dwg)
{
Expand Down Expand Up @@ -3214,6 +3307,8 @@ decode_R2004 (Bit_Chain *restrict dat, Dwg_Data *restrict dwg)
error |= read_2004_section_filedeplist (dat, dwg);
error |= read_2004_section_security (dat, dwg);
error |= read_2004_section_revhistory (dat, dwg);
error |= read_2004_section_objfreespace (dat, dwg);
error |= read_2004_section_template (dat, dwg);

/* Clean up. XXX? Need this to write the sections, at least the name and
* type
Expand Down
91 changes: 89 additions & 2 deletions src/decode_r2007.c
Original file line number Diff line number Diff line change
Expand Up @@ -1811,7 +1811,7 @@ read_2007_section_appinfo (Bit_Chain *restrict dat, Dwg_Data *restrict dwg,
return error;
}

/* AppInfoHistory Section
/* Unknown AppInfoHistory Section
*/
static int
read_2007_section_appinfohistory (Bit_Chain *restrict dat, Dwg_Data *restrict dwg,
Expand Down Expand Up @@ -1852,7 +1852,7 @@ read_2007_section_appinfohistory (Bit_Chain *restrict dat, Dwg_Data *restrict dw
return error;
}

/* RevHistory Section
/* Unknown RevHistory Section
*/
static int
read_2007_section_revhistory (Bit_Chain *restrict dat, Dwg_Data *restrict dwg,
Expand Down Expand Up @@ -1893,6 +1893,91 @@ read_2007_section_revhistory (Bit_Chain *restrict dat, Dwg_Data *restrict dwg,
return error;
}

/* ObjFreeSpace Section
*/
static int
read_2007_section_objfreespace (Bit_Chain *restrict dat, Dwg_Data *restrict dwg,
r2007_section *restrict sections_map,
r2007_page *restrict pages_map)
{
Bit_Chain old_dat, sec_dat = { 0 };
//Bit_Chain *str_dat;
struct Dwg_ObjFreeSpace *_obj = &dwg->objfreespace;
Dwg_Object *obj = NULL;
int error = 0;
BITCODE_RL rcount1 = 0, rcount2 = 0;

// compressed, page size: 0x7400
error = read_data_section (&sec_dat, dat, sections_map, pages_map,
SECTION_OBJFREESPACE);
if (error >= DWG_ERR_CRITICAL || !sec_dat.chain)
{
LOG_INFO ("%s section not found\n", "ObjFreeSpace");
if (sec_dat.chain)
free (sec_dat.chain);
return error;
}

LOG_TRACE ("\nObjFreeSpace\n-------------------\n")
old_dat = *dat;
dat = &sec_dat; // restrict in size

// clang-format off
#include "objfreespace.spec"
// clang-format on

LOG_TRACE ("\n")
if (sec_dat.chain)
free (sec_dat.chain);
*dat = old_dat; // unrestrict
return error;
}

/* Template Section. Optional r13-r15, mandatory r18+.
Contains the MEASUREMENT variable (0 = English, 1 = Metric).
*/
static int
read_2007_section_template (Bit_Chain *restrict dat, Dwg_Data *restrict dwg,
r2007_section *restrict sections_map,
r2007_page *restrict pages_map)
{
Bit_Chain old_dat, sec_dat = { 0 };
//Bit_Chain *str_dat;
struct Dwg_Template *_obj = &dwg->template;
Dwg_Object *obj = NULL;
int error = 0;
BITCODE_RL rcount1 = 0, rcount2 = 0;

// compressed
error = read_data_section (&sec_dat, dat, sections_map, pages_map,
SECTION_TEMPLATE);
if (error >= DWG_ERR_CRITICAL || !sec_dat.chain)
{
LOG_ERROR ("%s section not found\n", "Template");
if (sec_dat.chain)
free (sec_dat.chain);
return error | DWG_ERR_SECTIONNOTFOUND;
}

LOG_TRACE ("\nTemplate\n-------------------\n")
old_dat = *dat;
dat = &sec_dat; // restrict in size

// clang-format off
#include "template.spec"
// clang-format on

dwg->header_vars.MEASUREMENT = _obj->MEASUREMENT;
LOG_TRACE ("HEADER.MEASUREMENT: " FORMAT_BS " (0 English/1 Metric)\n",
dwg->header_vars.MEASUREMENT)

LOG_TRACE ("\n")
if (sec_dat.chain)
free (sec_dat.chain);
*dat = old_dat; // unrestrict
return error;
}

/* r21 FileDepList Section
*/
static int
Expand Down Expand Up @@ -2111,6 +2196,8 @@ read_r2007_meta_data (Bit_Chain *dat, Bit_Chain *hdl_dat,
error |= read_2007_section_filedeplist (dat, dwg, sections_map, pages_map);
error |= read_2007_section_security (dat, dwg, sections_map, pages_map);
error |= read_2007_section_revhistory (dat, dwg, sections_map, pages_map);
error |= read_2007_section_objfreespace (dat, dwg, sections_map, pages_map);
error |= read_2007_section_template (dat, dwg, sections_map, pages_map);
// read_2007_blocks (dat, hdl_dat, dwg, sections_map, pages_map);

error:
Expand Down
2 changes: 2 additions & 0 deletions src/free.c
Original file line number Diff line number Diff line change
Expand Up @@ -847,6 +847,8 @@ dwg_free (Dwg_Data *dwg)
FREE_IF (dwg->vbaproject.unknown_bits);
FREE_IF (dwg->revhistory.unknown_bits);
FREE_IF (dwg->appinfohistory.unknown_bits);
//FREE_IF (dwg->objfreespace...);
FREE_IF (dwg->template.desc);
FREE_IF (dwg->header.section);
for (i = 0; i < dwg->second_header.num_handlers; i++)
FREE_IF (dwg->second_header.handlers[i].data);
Expand Down
48 changes: 48 additions & 0 deletions src/objfreespace.spec
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/* -*- c -*- */
/*****************************************************************************/
/* LibreDWG - free implementation of the DWG file format */
/* */
/* Copyright (C) 2020 Free Software Foundation, Inc. */
/* */
/* This library is free software, licensed under the terms of the GNU */
/* General Public License as published by the Free Software Foundation, */
/* either version 3 of the License, or (at your option) any later version. */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/*****************************************************************************/

/*
* objfreespace.spec: AcDb:ObjFreeSpace section specification
* written by Reini Urban
*/

#include "spec.h"

UNTIL (R_2007)
{
FIELD_CAST (zero, RL, RLL, 0);
FIELD_CAST (num_handles, RL, RLL, 0);
FIELD_TIMERLL (TDUPDATE, 0);
FIELD_RLx (objects_address, 0);
FIELD_RC (num_nums, 0);
FIELD_RLL (max32, 0); // 0x32
FIELD_RLL (max64, 0); // 0x64
FIELD_RLL (maxtbl, 0); // 0x200
FIELD_RLL (maxrl, 0); // 0xffffffff
}
LATER_VERSIONS {
FIELD_RLL (zero, 0);
FIELD_RLL (num_handles, 0);
FIELD_TIMERLL (TDUPDATE, 0);
FIELD_RC (num_nums, 0);
// num types are not 64 bit, but 128
FIELD_RLL (max32, 0); // 0x32
FIELD_RLL (max32_hi, 0); //
FIELD_RLL (max64, 0); // 0x64
FIELD_RLL (max64_hi, 0); // 0x0
FIELD_RLL (maxtbl, 0); // 0x200
FIELD_RLL (maxtbl_hi, 0); // 0x0
FIELD_RLL (maxrl, 0); // 0xffffffff
FIELD_RLL (maxrl_hi, 0); // 0x0
}
DEBUG_HERE
Loading

0 comments on commit 261cb96

Please # to comment.