1 /*****************************************************************************/
2 /* LibreDWG - free implementation of the DWG file format */
3 /* */
4 /* Copyright (C) 2010-2021 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_r2007.c: functions to decode R2007 (AC1021) sections
15 * written by Till Heuschmann
16 * modified by Reini Urban
17 */
18
19 #define IS_DECODER
20
21 #include "config.h"
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <stdint.h>
26 #include <sys/types.h>
27 #include <stdbool.h>
28 #include <assert.h>
29 #include "common.h"
30 #include "bits.h"
31 #include "decode.h"
32 #include "dynapi.h"
33
34 /* The logging level for the read (decode) path. */
35 static unsigned int loglevel;
36 /* the current version per spec block */
37 static unsigned int cur_ver = 0;
38
39 #define DWG_LOGLEVEL loglevel
40 #include "logging.h"
41 #include "dec_macros.h"
42
43 // only for temp. debugging, to abort on obviously wrong sizes.
44 // should be a bit larger then the filesize.
45 #define DBG_MAX_COUNT 0x100000
46 #define DBG_MAX_SIZE 0xff0000 /* should be dat->size */
47
48 typedef struct r2007_file_header
49 {
50 int64_t header_size; // 0x70
51 int64_t file_size;
52 int64_t pages_map_crc_compressed;
53 int64_t pages_map_correction;
54 int64_t pages_map_crc_seed;
55 int64_t pages_map2_offset;
56 int64_t pages_map2_id;
57 int64_t pages_map_offset; // starting address of the Page Map section
58 int64_t pages_map_id;
59 int64_t header2_offset;
60 int64_t pages_map_size_comp; // the compressed size of section
61 int64_t pages_map_size_uncomp;
62 int64_t pages_amount;
63 int64_t pages_maxid;
64 int64_t unknown1; // 0x20
65 int64_t unknown2; // 0x40
66 int64_t pages_map_crc_uncomp;
67 int64_t unknown3; // 0xf800
68 int64_t unknown4; // 4
69 int64_t unknown5; // 1
70 int64_t num_sections;
71 int64_t sections_map_crc_uncomp;
72 int64_t sections_map_size_comp;
73 int64_t sections_map2_id;
74 int64_t sections_map_id;
75 int64_t sections_map_size_uncomp;
76 int64_t sections_map_crc_comp;
77 int64_t sections_map_correction;
78 int64_t sections_map_crc_seed;
79 int64_t stream_version; // 0x60100
80 int64_t crc_seed;
81 int64_t crc_seed_encoded;
82 int64_t random_seed;
83 int64_t header_crc;
84 } r2007_file_header;
85
86 /* page map */
87 typedef struct _r2007_page
88 {
89 int64_t id;
90 uint64_t size;
91 uint64_t offset;
92 struct _r2007_page *next;
93 } r2007_page;
94
95 /* section page */
96 typedef struct _r2007_section_page
97 {
98 uint64_t offset;
99 uint64_t size;
100 int64_t id;
101 uint64_t uncomp_size; // src_size
102 uint64_t comp_size;
103 uint64_t checksum;
104 uint64_t crc;
105 } r2007_section_page;
106
107 /* section map */
108 typedef struct _r2007_section
109 {
110 uint64_t data_size; // max size of page
111 uint64_t max_size;
112 int64_t encrypted;
113 uint64_t hashcode; // checksum in r2004
114 int64_t name_length; // 0x22
115 int64_t unknown; // 0x00
116 int64_t encoded;
117 int64_t num_pages;
118 DWGCHAR *name;
119 Dwg_Section_Type type;
120 r2007_section_page **pages;
121 struct _r2007_section *next;
122 } r2007_section;
123
124 /* imported */
125 int rs_decode_block (BITCODE_RC *blk, int fix);
126
127 /* private */
128 static r2007_section *get_section (r2007_section *sections_map,
129 Dwg_Section_Type sec_type);
130 static r2007_page *get_page (r2007_page *pages_map, int64_t id);
131 static void pages_destroy (r2007_page *page);
132 static void sections_destroy (r2007_section *section);
133 static r2007_section *read_sections_map (Bit_Chain *dat, int64_t size_comp,
134 int64_t size_uncomp,
135 int64_t correction) ATTRIBUTE_MALLOC;
136 static int read_data_section (Bit_Chain *sec_dat, Bit_Chain *dat,
137 r2007_section *restrict sections_map,
138 r2007_page *restrict pages_map,
139 Dwg_Section_Type sec_type);
140 static int read_2007_section_classes (Bit_Chain *restrict dat,
141 Dwg_Data *restrict dwg,
142 r2007_section *restrict sections_map,
143 r2007_page *restrict pages_map);
144 static int read_2007_section_header (Bit_Chain *dat, Bit_Chain *hdl_dat,
145 Dwg_Data *restrict dwg,
146 r2007_section *restrict sections_map,
147 r2007_page *restrict pages_map);
148 static int read_2007_section_handles (Bit_Chain *dat, Bit_Chain *hdl_dat,
149 Dwg_Data *restrict dwg,
150 r2007_section *restrict sections_map,
151 r2007_page *restrict pages_map);
152 static int read_2007_section_summary (Bit_Chain *restrict dat,
153 Dwg_Data *restrict dwg,
154 r2007_section *restrict sections_map,
155 r2007_page *restrict pages_map);
156 static int read_2007_section_preview (Bit_Chain *restrict dat,
157 Dwg_Data *restrict dwg,
158 r2007_section *restrict sections_map,
159 r2007_page *restrict pages_map);
160 static r2007_page *read_pages_map (Bit_Chain *dat, int64_t size_comp,
161 int64_t size_uncomp,
162 int64_t correction) ATTRIBUTE_MALLOC;
163 static int read_file_header (Bit_Chain *restrict dat,
164 r2007_file_header *restrict file_header);
165 static void read_instructions (BITCODE_RC *restrict *restrict src,
166 BITCODE_RC *restrict opcode,
167 uint32_t *restrict offset,
168 uint32_t *restrict length);
169 static inline BITCODE_RC *copy_bytes_2 (BITCODE_RC *restrict dst,
170 const BITCODE_RC *restrict src);
171 static inline BITCODE_RC *copy_bytes_3 (BITCODE_RC *restrict dst,
172 const BITCODE_RC *restrict src);
173 static void copy_bytes (BITCODE_RC *dst, uint32_t length, uint32_t offset);
174 static uint32_t read_literal_length (BITCODE_RC *restrict *restrict src,
175 unsigned char opcode);
176 static void copy_compressed_bytes (BITCODE_RC *restrict dst,
177 BITCODE_RC *restrict src,
178 int length);
179 static DWGCHAR *bfr_read_string (BITCODE_RC *restrict *restrict src,
180 int64_t size) ATTRIBUTE_MALLOC;
181 static BITCODE_RC *decode_rs (const BITCODE_RC *src, int block_count,
182 int data_size, const unsigned src_size) ATTRIBUTE_MALLOC;
183 static int decompress_r2007 (BITCODE_RC *restrict dst, const unsigned dst_size,
184 BITCODE_RC *restrict src, const unsigned src_size);
185
186 #define copy_1(offset) *dst++ = *(src + offset);
187
188 #define copy_2(offset) dst = copy_bytes_2 (dst, src + offset);
189
190 #define copy_3(offset) dst = copy_bytes_3 (dst, src + offset)
191
192 // 4 and 8 is not reverse, 16 is
193 #define copy_n(n, offset) \
194 memcpy (dst, &src[offset], n); \
195 dst += n
196
197 #define copy_4(offset) copy_n (4, offset)
198 #define copy_8(offset) copy_n (8, offset)
199 #define copy_16(offset) \
200 memcpy (dst, &src[offset + 8], 8); \
201 memcpy (&dst[8], &src[offset], 8); \
202 dst += 16
203
204 /* Don't use restrict here: GH #141 broken for most newer compilers */
205 static inline BITCODE_RC *
copy_bytes_2(BITCODE_RC * dst,const BITCODE_RC * src)206 copy_bytes_2 (BITCODE_RC *dst, const BITCODE_RC *src)
207 {
208 dst[0] = src[1];
209 dst[1] = src[0];
210 return dst + 2;
211 }
212
213 static inline BITCODE_RC *
copy_bytes_3(BITCODE_RC * dst,const BITCODE_RC * src)214 copy_bytes_3 (BITCODE_RC *dst, const BITCODE_RC *src)
215 {
216 dst[0] = src[2];
217 dst[1] = src[1];
218 dst[2] = src[0];
219 return dst + 3;
220 }
221
222 static void
copy_bytes(BITCODE_RC * dst,uint32_t length,uint32_t offset)223 copy_bytes (BITCODE_RC *dst, uint32_t length, uint32_t offset)
224 {
225 BITCODE_RC *src = dst - offset;
226
227 while (length-- > 0)
228 *dst++ = *src++;
229 }
230
231 /* See spec version 5.0 page 30 */
232 static void
copy_compressed_bytes(BITCODE_RC * restrict dst,BITCODE_RC * restrict src,int length)233 copy_compressed_bytes (BITCODE_RC *restrict dst, BITCODE_RC *restrict src,
234 int length)
235 {
236 while (length >= 32)
237 {
238 copy_16 (16);
239 copy_16 (0);
240
241 src += 32;
242 length -= 32;
243 }
244
245 switch (length)
246 {
247 case 0:
248 break;
249 case 1:
250 copy_1 (0);
251 break;
252 case 2:
253 copy_2 (0);
254 break;
255 case 3:
256 copy_3 (0);
257 break;
258 case 4:
259 copy_4 (0);
260 break;
261 case 5:
262 copy_1 (4);
263 copy_4 (0);
264 break;
265 case 6:
266 copy_1 (5);
267 copy_4 (1);
268 copy_1 (0);
269 break;
270 case 7:
271 copy_2 (5);
272 copy_4 (1);
273 copy_1 (0);
274 break;
275 case 8:
276 copy_8 (0);
277 break;
278 case 9:
279 copy_1 (8);
280 copy_8 (0);
281 break;
282 case 10:
283 copy_1 (9);
284 copy_8 (1);
285 copy_1 (0);
286 break;
287 case 11:
288 copy_2 (9);
289 copy_8 (1);
290 copy_1 (0);
291 break;
292 case 12:
293 copy_4 (8);
294 copy_8 (0);
295 break;
296 case 13:
297 copy_1 (12);
298 copy_4 (8);
299 copy_8 (0);
300 break;
301 case 14:
302 copy_1 (13);
303 copy_4 (9);
304 copy_8 (1);
305 copy_1 (0);
306 break;
307 case 15:
308 copy_2 (13);
309 copy_4 (9);
310 copy_8 (1);
311 copy_1 (0);
312 break;
313 case 16:
314 copy_16 (0);
315 break;
316 case 17:
317 copy_8 (9);
318 copy_1 (8);
319 copy_8 (0);
320 break;
321 case 18:
322 copy_1 (17);
323 copy_16 (1);
324 copy_1 (0);
325 break;
326 case 19:
327 copy_3 (16);
328 copy_16 (0);
329 break;
330 case 20:
331 copy_4 (16);
332 copy_16 (0);
333 break;
334 case 21:
335 copy_1 (20);
336 copy_4 (16);
337 copy_16 (0);
338 break;
339 case 22:
340 copy_2 (20);
341 copy_4 (16);
342 copy_16 (0);
343 break;
344 case 23:
345 copy_3 (20);
346 copy_4 (16);
347 copy_16 (0);
348 break;
349 case 24:
350 copy_8 (16);
351 copy_16 (0);
352 break;
353 case 25:
354 copy_8 (17);
355 copy_1 (16);
356 copy_16 (0);
357 break;
358 case 26:
359 copy_1 (25);
360 copy_8 (17);
361 copy_1 (16);
362 copy_16 (0);
363 break;
364 case 27:
365 copy_2 (25);
366 copy_8 (17);
367 copy_1 (16);
368 copy_16 (0);
369 break;
370 case 28:
371 copy_4 (24);
372 copy_8 (16);
373 copy_16 (0);
374 break;
375 case 29:
376 copy_1 (28);
377 copy_4 (24);
378 copy_8 (16);
379 copy_16 (0);
380 break;
381 case 30:
382 copy_2 (28);
383 copy_4 (24);
384 copy_8 (16);
385 copy_16 (0);
386 break;
387 case 31:
388 copy_1 (30);
389 copy_4 (26);
390 copy_8 (18);
391 copy_16 (2);
392 copy_2 (0);
393 break;
394 default:
395 LOG_ERROR ("Wrong length %d", length);
396 }
397 }
398
399 /* See spec version 5.1 page 50 */
400 static uint32_t
read_literal_length(BITCODE_RC * restrict * src,unsigned char opcode)401 read_literal_length (BITCODE_RC *restrict *src, unsigned char opcode)
402 {
403 uint32_t length = opcode + 8;
404
405 if (length == 0x17)
406 {
407 int n = *(*src)++;
408
409 length += n;
410
411 if (n == 0xff)
412 {
413 do
414 {
415 n = *(*src)++;
416 n |= (*(*src)++ << 8);
417
418 length += n;
419 }
420 while (n == 0xFFFF);
421 }
422 }
423
424 return length;
425 }
426
427 /* See spec version 5.1 page 53 */
428 static void
read_instructions(BITCODE_RC * restrict * src,unsigned char * restrict opcode,uint32_t * restrict offset,uint32_t * restrict length)429 read_instructions (BITCODE_RC *restrict *src, unsigned char *restrict opcode,
430 uint32_t *restrict offset, uint32_t *restrict length)
431 {
432 switch (*opcode >> 4)
433 {
434 case 0:
435 *length = (*opcode & 0xf) + 0x13;
436 *offset = *(*src)++;
437 *opcode = *(*src)++;
438 *length = ((*opcode >> 3) & 0x10) + *length;
439 *offset = ((*opcode & 0x78) << 5) + 1 + *offset;
440 break;
441
442 case 1:
443 *length = (*opcode & 0xf) + 3;
444 *offset = *(*src)++;
445 *opcode = *(*src)++;
446 *offset = ((*opcode & 0xf8) << 5) + 1 + *offset;
447 break;
448
449 case 2:
450 *offset = *(*src)++;
451 *offset = ((*(*src)++ << 8) & 0xff00) | *offset;
452 *length = *opcode & 7;
453
454 if ((*opcode & 8) == 0)
455 {
456 *opcode = *(*src)++;
457 *length = (*opcode & 0xf8) + *length;
458 }
459 else
460 {
461 (*offset)++;
462 *length = (*(*src)++ << 3) + *length;
463 *opcode = *(*src)++;
464 *length = (((*opcode & 0xf8) << 8) + *length) + 0x100;
465 }
466 break;
467
468 default:
469 *length = *opcode >> 4;
470 *offset = *opcode & 15;
471 *opcode = *(*src)++;
472 *offset = (((*opcode & 0xf8) << 1) + *offset) + 1;
473 break;
474 }
475 }
476
477 /* par 4.7 Compression, page 32 (same as format 2004)
478 TODO: replace by decompress_R2004_section(dat, decomp, comp_data_size)
479 */
480 static int
decompress_r2007(BITCODE_RC * restrict dst,const unsigned dst_size,BITCODE_RC * restrict src,const unsigned src_size)481 decompress_r2007 (BITCODE_RC *restrict dst, const unsigned dst_size,
482 BITCODE_RC *restrict src, const unsigned src_size)
483 {
484 uint32_t length = 0;
485 uint32_t offset = 0;
486
487 BITCODE_RC *dst_start = dst;
488 BITCODE_RC *dst_end = dst + dst_size;
489 BITCODE_RC *src_end = src + src_size;
490 unsigned char opcode;
491
492 LOG_INSANE ("decompress_r2007 (%p, %d, %p, %d)\n", dst, dst_size, src, src_size);
493 if (!dst || !src || !dst_size || src_size < 2)
494 {
495 LOG_ERROR ("Invalid argument to %s\n", __FUNCTION__);
496 return DWG_ERR_INTERNALERROR;
497 }
498
499 opcode = *src++;
500 if ((opcode & 0xf0) == 0x20)
501 {
502 src += 2;
503 length = *src++ & 0x07;
504 if (length == 0)
505 {
506 LOG_ERROR ("Decompression error: zero length")
507 return DWG_ERR_INTERNALERROR;
508 }
509 }
510
511 while (src < src_end)
512 {
513 if (length == 0)
514 length = read_literal_length (&src, opcode);
515
516 if ((dst + length) > dst_end || (src + length) > src_end)
517 {
518 LOG_ERROR ("Decompression error: length overflow");
519 return DWG_ERR_INTERNALERROR;
520 }
521
522 LOG_INSANE("copy_compressed_bytes (%p, %p, %u)\n", dst, src, length);
523 copy_compressed_bytes (dst, src, length);
524
525 dst += length;
526 src += length;
527
528 length = 0;
529
530 if (src >= src_end)
531 return 0;
532
533 opcode = *src++;
534
535 read_instructions (&src, &opcode, &offset, &length);
536
537 while (1)
538 {
539 if ((dst + length) > dst_end)
540 {
541 LOG_ERROR ("Decompression error: length overflow");
542 return DWG_ERR_INTERNALERROR;
543 }
544 if (offset > (uint32_t) (dst - dst_start))
545 {
546 LOG_ERROR ("Decompression error: offset underflow");
547 return DWG_ERR_INTERNALERROR;
548 }
549 LOG_INSANE ("copy_bytes (%p, %u, %u)\n", dst, length, offset);
550 copy_bytes (dst, length, offset);
551
552 dst += length;
553 length = (opcode & 7);
554
555 if (length != 0 || src >= src_end)
556 break;
557
558 opcode = *src++;
559
560 if ((opcode >> 4) == 0)
561 break;
562
563 if ((opcode >> 4) == 0x0f)
564 opcode &= 0xf;
565
566 read_instructions ((unsigned char **)&src, &opcode, &offset,
567 &length);
568 }
569 }
570
571 return 0;
572 }
573
574 // reed-solomon (255, 239) encoding with factor 3
575 // TODO: for now disabled, until we get proper data
576 ATTRIBUTE_MALLOC
577 static BITCODE_RC *
decode_rs(const BITCODE_RC * src,int block_count,int data_size,const unsigned src_size)578 decode_rs (const BITCODE_RC *src, int block_count, int data_size,
579 const unsigned src_size)
580 {
581 int i, j;
582 const BITCODE_RC *src_base = src;
583 BITCODE_RC *dst_base, *dst;
584 // TODO: round up data_size from 239 to 255
585
586 if ((unsigned long)block_count * data_size > src_size)
587 {
588 LOG_ERROR ("decode_rs src overflow: %ld > %u",
589 (long)block_count * data_size, src_size)
590 return NULL;
591 }
592 dst_base = dst = (BITCODE_RC *)calloc (block_count, data_size);
593 if (!dst)
594 {
595 LOG_ERROR ("Out of memory")
596 return NULL;
597 }
598
599 for (i = 0; i < block_count; ++i)
600 {
601 for (j = 0; j < data_size; ++j)
602 {
603 *dst++ = *src;
604 src += block_count;
605 }
606
607 // rs_decode_block((unsigned char*)(dst_base + 239*i), 1);
608 src = ++src_base;
609 }
610
611 return dst_base;
612 }
613
614 ATTRIBUTE_MALLOC
615 static BITCODE_RC *
read_system_page(Bit_Chain * dat,int64_t size_comp,int64_t size_uncomp,int64_t repeat_count)616 read_system_page (Bit_Chain *dat, int64_t size_comp, int64_t size_uncomp,
617 int64_t repeat_count)
618 {
619 int i;
620 int error = 0;
621
622 int64_t pesize; // Pre RS encoded size
623 int64_t block_count; // Number of RS encoded blocks
624 int64_t page_size;
625 long pedata_size;
626
627 BITCODE_RC *rsdata; // RS encoded data
628 BITCODE_RC *pedata; // Pre RS encoded data
629 BITCODE_RC *data; // The data RS unencoded and uncompressed
630
631 if (repeat_count < 0 ||
632 repeat_count > DBG_MAX_COUNT ||
633 (uint64_t)size_comp >= dat->size ||
634 (uint64_t)size_uncomp >= dat->size)
635 {
636 LOG_ERROR ("Invalid r2007 system page: "
637 "size_comp: %" PRId64 ", size_uncomp: %" PRId64
638 ", repeat_count: %" PRId64, size_comp, size_uncomp, repeat_count);
639 return NULL;
640 }
641 // Round to a multiple of 8
642 pesize = ((size_comp + 7) & ~7) * repeat_count;
643 // Divide pre encoded size by RS k-value (239)
644 block_count = (pesize + 238) / 239;
645 if (block_count <= 0 || block_count > DBG_MAX_COUNT)
646 {
647 LOG_ERROR ("Invalid r2007 system page: size_comp: %" PRId64
648 ", size_uncomp: %" PRId64, size_comp, size_uncomp);
649 return NULL;
650 }
651 // Multiply with codeword size (255) and round to a multiple of 8
652 page_size = (block_count * 255 + 7) & ~7;
653 if ((uint64_t)page_size >= DBG_MAX_COUNT || (unsigned long)page_size > dat->size - dat->byte)
654 {
655 LOG_ERROR ("Invalid r2007 system page: page_size: %" PRId64, page_size);
656 return NULL;
657 }
658 assert ((uint64_t)size_comp < dat->size);
659 assert ((uint64_t)size_uncomp < dat->size);
660 assert ((uint64_t)repeat_count < DBG_MAX_COUNT);
661 assert ((uint64_t)page_size < DBG_MAX_COUNT);
662 data = (BITCODE_RC *)calloc (size_uncomp + page_size, 1);
663 LOG_HANDLE ("Alloc system page of size %" PRId64 "\n", size_uncomp + page_size)
664 if (!data)
665 {
666 LOG_ERROR ("Out of memory")
667 return NULL;
668 }
669
670 rsdata = &data[size_uncomp];
671 bit_read_fixed (dat, rsdata, page_size);
672 pedata_size = block_count * 239;
673 pedata = decode_rs (rsdata, block_count, 239, page_size);
674 if (!pedata)
675 {
676 free (data);
677 return NULL;
678 }
679
680 if (size_comp < size_uncomp)
681 error = decompress_r2007 (data, size_uncomp, pedata, MIN (pedata_size, size_comp));
682 else
683 memcpy (data, pedata, size_uncomp);
684
685 free (pedata);
686 if (error >= DWG_ERR_CRITICAL)
687 {
688 free (data);
689 return NULL;
690 }
691 return data;
692 }
693
694 static int
read_data_page(Bit_Chain * restrict dat,BITCODE_RC * restrict decomp,int64_t page_size,int64_t size_comp,int64_t size_uncomp)695 read_data_page (Bit_Chain *restrict dat, BITCODE_RC *restrict decomp,
696 int64_t page_size, int64_t size_comp, int64_t size_uncomp)
697 {
698 int i;
699 int error = 0;
700
701 int64_t pesize; // Pre RS encoded size
702 int64_t block_count; // Number of RS encoded blocks
703
704 BITCODE_RC *rsdata; // RS encoded data
705 BITCODE_RC *pedata; // Pre RS encoded data
706 long pedata_size;
707
708 // Round to a multiple of 8
709 pesize = ((size_comp + 7) & ~7);
710 block_count = (pesize + 0xFB - 1) / 0xFB;
711 pedata_size = block_count * 0xFB;
712
713 rsdata = (BITCODE_RC *)calloc (1, page_size);
714 if (rsdata == NULL)
715 {
716 LOG_ERROR ("Out of memory")
717 return DWG_ERR_OUTOFMEM;
718 }
719 bit_read_fixed (dat, rsdata, page_size);
720 pedata = decode_rs (rsdata, block_count, 0xFB, page_size);
721 if (!pedata)
722 {
723 free (rsdata);
724 return DWG_ERR_OUTOFMEM;
725 }
726
727 if (size_comp < size_uncomp)
728 error = decompress_r2007 (decomp, size_uncomp, pedata,
729 MIN (pedata_size, size_comp));
730 else
731 memcpy (decomp, pedata, size_uncomp);
732
733 free (pedata);
734 free (rsdata);
735
736 return error;
737 }
738
739 static int
read_data_section(Bit_Chain * sec_dat,Bit_Chain * dat,r2007_section * restrict sections_map,r2007_page * restrict pages_map,Dwg_Section_Type sec_type)740 read_data_section (Bit_Chain *sec_dat, Bit_Chain *dat,
741 r2007_section *restrict sections_map,
742 r2007_page *restrict pages_map, Dwg_Section_Type sec_type)
743 {
744 r2007_section *section;
745 r2007_page *page;
746 uint64_t max_decomp_size;
747 BITCODE_RC *decomp;
748 int error = 0, i;
749
750 section = get_section (sections_map, sec_type);
751 sec_dat->chain = NULL;
752 if (section == NULL)
753 {
754 if (sec_type < SECTION_REVHISTORY
755 && sec_type != SECTION_TEMPLATE
756 && sec_type != SECTION_OBJFREESPACE)
757 {
758 LOG_WARN ("Failed to find section_info[%u]", (int)sec_type)
759 return DWG_ERR_SECTIONNOTFOUND;
760 }
761 else
762 {
763 LOG_TRACE ("Found no section_info[%u]\n", (int)sec_type)
764 return DWG_ERR_VALUEOUTOFBOUNDS;
765 }
766 }
767
768 max_decomp_size = section->data_size;
769 if (max_decomp_size > 0x2f000000) // 790Mb
770 {
771 LOG_ERROR ("Invalid max decompression size %" PRIu64, max_decomp_size);
772 return DWG_ERR_INVALIDDWG;
773 }
774 decomp = (BITCODE_RC *)calloc (max_decomp_size, 1);
775 if (decomp == NULL)
776 {
777 LOG_ERROR ("Out of memory")
778 return DWG_ERR_OUTOFMEM;
779 }
780 LOG_HANDLE ("Alloc data section of size %" PRIu64 "\n", max_decomp_size)
781
782 sec_dat->bit = 0;
783 sec_dat->byte = 0;
784 sec_dat->size = max_decomp_size;
785 sec_dat->version = dat->version;
786 sec_dat->from_version = dat->from_version;
787
788 for (i = 0; i < (int)section->num_pages; i++)
789 {
790 r2007_section_page *section_page = section->pages[i];
791 page = get_page (pages_map, section_page->id);
792 if (page == NULL)
793 {
794 free (decomp);
795 LOG_ERROR ("Failed to find page %d", (int)section_page->id)
796 return DWG_ERR_PAGENOTFOUND;
797 }
798 if (section_page->offset > max_decomp_size)
799 {
800 free (decomp);
801 LOG_ERROR ("Invalid section_page->offset %ld > %ld",
802 (long)section_page->offset, (long)max_decomp_size)
803 return DWG_ERR_VALUEOUTOFBOUNDS;
804 }
805
806 dat->byte = page->offset;
807 // only if compressed. TODO: Isn't there a compressed flag as with 2004+?
808 // theoretically the sizes could still be the same.
809 if (section_page->comp_size != section_page->uncomp_size)
810 {
811 error = read_data_page (dat, &decomp[section_page->offset],
812 page->size, section_page->comp_size,
813 section_page->uncomp_size);
814 if (error)
815 {
816 free (decomp);
817 LOG_ERROR ("Failed to read compressed page")
818 return error;
819 }
820 }
821 else
822 {
823 memcpy (&decomp[section_page->offset], &dat->chain[dat->byte],
824 section_page->uncomp_size);
825 }
826 }
827 sec_dat->chain = decomp;
828 return 0;
829 }
830
831 /* endian specific code: */
832 #define bfr_read_int16(_p) \
833 *((int16_t *)_p); \
834 _p += 2;
835 #define bfr_read_int64(_p) \
836 *((int64_t *)_p); \
837 _p += 8;
838 #define bfr_read_uint64(_p) \
839 *((uint64_t *)_p); \
840 _p += 8;
841
842 static DWGCHAR *
bfr_read_string(BITCODE_RC * restrict * restrict src,int64_t size)843 bfr_read_string (BITCODE_RC *restrict *restrict src, int64_t size)
844 {
845 uint16_t *ptr = (uint16_t *)*src;
846 int32_t length = 0, wsize;
847 DWGCHAR *str, *str_base;
848 int i;
849
850 if (size <= 0)
851 return NULL;
852 while (*ptr != 0 && length * 2 < size)
853 {
854 ptr++;
855 length++;
856 }
857
858 wsize = length * sizeof (DWGCHAR) + sizeof (DWGCHAR);
859
860 str = str_base = (DWGCHAR *)malloc (wsize);
861 if (!str)
862 {
863 LOG_ERROR ("Out of memory");
864 return NULL;
865 }
866 ptr = (uint16_t *)*src;
867 for (i = 0; i < length; i++)
868 {
869 *str++ = (DWGCHAR) (*ptr++);
870 }
871
872 *src += size;
873 *str = 0;
874
875 return str_base;
876 }
877
878 static r2007_section *
read_sections_map(Bit_Chain * dat,int64_t size_comp,int64_t size_uncomp,int64_t correction)879 read_sections_map (Bit_Chain *dat, int64_t size_comp, int64_t size_uncomp,
880 int64_t correction)
881 {
882 BITCODE_RC *data;
883 r2007_section *sections = NULL, *last_section = NULL, *section = NULL;
884 BITCODE_RC *ptr, *ptr_end;
885 int i, j = 0;
886
887 data = read_system_page (dat, size_comp, size_uncomp, correction);
888 if (!data)
889 {
890 LOG_ERROR ("Failed to read system page")
891 return NULL;
892 }
893
894 ptr = data;
895 ptr_end = data + size_uncomp;
896
897 LOG_TRACE ("\n=== System Section (Section Map) ===\n")
898
899 while (ptr < ptr_end)
900 {
901 section = (r2007_section *)calloc (1, sizeof (r2007_section));
902 if (!section)
903 {
904 LOG_ERROR ("Out of memory");
905 free (data);
906 sections_destroy (sections); // the root
907 return NULL;
908 }
909
910 bfr_read (section, &ptr, 64);
911
912 LOG_TRACE ("\nSection [%d]:\n", j)
913 LOG_TRACE (" data size: %" PRIu64 "\n", section->data_size)
914 LOG_TRACE (" max size: %" PRIu64 "\n", section->max_size)
915 LOG_TRACE (" encryption: %" PRIu64 "\n", section->encrypted)
916 LOG_HANDLE (" hashcode: %" PRIx64 "\n", section->hashcode)
917 LOG_HANDLE (" name length: %" PRIu64 "\n", section->name_length)
918 LOG_TRACE (" unknown: %" PRIu64 "\n", section->unknown)
919 LOG_TRACE (" encoding: %" PRIu64 "\n", section->encoded)
920 LOG_TRACE (" num pages: %" PRIu64 "\n", section->num_pages);
921
922 // debugging sanity
923 #if 1
924 /* compressed */
925 if (section->data_size > 10 * dat->size
926 || section->name_length >= (int64_t)dat->size)
927 {
928 LOG_ERROR ("Invalid System Section");
929 free (section);
930 free (data);
931 sections_destroy (sections); // the root
932 return NULL;
933 }
934 // assert(section->data_size < dat->size + 0x100000);
935 // assert(section->max_size < dat->size + 0x100000);
936 // assert(section->num_pages < DBG_MAX_COUNT);
937 #endif
938 // section->next = NULL;
939 // section->pages = NULL;
940 // section->name = NULL;
941
942 if (!sections)
943 {
944 sections = last_section = section;
945 }
946 else
947 {
948 last_section->next = section;
949 last_section = section;
950 }
951
952 j++;
953 if (ptr >= ptr_end)
954 break;
955
956 // Section Name (wchar)
957 section->name = bfr_read_string (&ptr, section->name_length);
958 #ifdef HAVE_NATIVE_WCHAR2
959 LOG_TRACE (" name: " FORMAT_TU "\n\n",
960 (BITCODE_TU)section->name)
961 #else
962 LOG_TRACE (" name: ")
963 LOG_TEXT_UNICODE (TRACE, section->name)
964 LOG_TRACE ("\n\n")
965 #endif
966 section->type = dwg_section_wtype (section->name);
967
968 if (section->num_pages <= 0)
969 continue;
970 if (section->num_pages > 0xf0000)
971 {
972 LOG_ERROR ("Invalid num_pages %lu, skip", (unsigned long)section->num_pages);
973 continue;
974 }
975
976 section->pages = (r2007_section_page **)calloc (
977 (size_t)section->num_pages, sizeof (r2007_section_page *));
978 if (!section->pages)
979 {
980 LOG_ERROR ("Out of memory");
981 free (data);
982 if (sections)
983 sections_destroy (sections); // the root
984 else
985 sections_destroy (section);
986 return NULL;
987 }
988
989 for (i = 0; i < section->num_pages; i++)
990 {
991 section->pages[i]
992 = (r2007_section_page *)calloc (1, sizeof (r2007_section_page));
993 if (!section->pages[i])
994 {
995 LOG_ERROR ("Out of memory");
996 free (data);
997 if (sections)
998 sections_destroy (sections); // the root
999 else
1000 sections_destroy (section);
1001 return NULL;
1002 }
1003
1004 if (ptr + 56 >= ptr_end)
1005 {
1006 LOG_ERROR ("Section[%d]->pages[%d] overflow", j, i);
1007 free (section->pages[i]);
1008 section->num_pages = i; // skip this last section
1009 break;
1010 }
1011 bfr_read (section->pages[i], &ptr, 56);
1012
1013 LOG_TRACE (" Page[%d]: ", i)
1014 LOG_TRACE (" offset: 0x%07" PRIx64, section->pages[i]->offset);
1015 LOG_TRACE (" size: %5" PRIu64, section->pages[i]->size);
1016 LOG_TRACE (" id: %4" PRIu64, section->pages[i]->id);
1017 LOG_TRACE (" uncomp_size: %5" PRIu64 "\n",
1018 section->pages[i]->uncomp_size);
1019 LOG_HANDLE (" comp_size: %5" PRIu64, section->pages[i]->comp_size);
1020 LOG_HANDLE (" checksum: %016" PRIx64, section->pages[i]->checksum);
1021 LOG_HANDLE (" crc64: %016" PRIx64 "\n", section->pages[i]->crc);
1022 // debugging sanity
1023 if (section->pages[i]->size >= DBG_MAX_SIZE
1024 || section->pages[i]->uncomp_size >= DBG_MAX_SIZE
1025 || section->pages[i]->comp_size >= DBG_MAX_SIZE)
1026 {
1027 LOG_ERROR ("Invalid section->pages[%d] size", i);
1028 free (data);
1029 free (section->pages[i]);
1030 section->num_pages = i; // skip this last section
1031 return sections;
1032 }
1033 assert (section->pages[i]->size < DBG_MAX_SIZE);
1034 assert (section->pages[i]->uncomp_size < DBG_MAX_SIZE);
1035 assert (section->pages[i]->comp_size < DBG_MAX_SIZE);
1036 }
1037 }
1038
1039 free (data);
1040 return sections;
1041 }
1042
1043 static r2007_page *
read_pages_map(Bit_Chain * dat,int64_t size_comp,int64_t size_uncomp,int64_t correction)1044 read_pages_map (Bit_Chain *dat, int64_t size_comp, int64_t size_uncomp,
1045 int64_t correction)
1046 {
1047 BITCODE_RC *data, *ptr, *ptr_end;
1048 r2007_page *pages = NULL, *last_page = NULL, *page;
1049 int64_t offset = 0x480; // dat->byte;
1050 // int64_t index;
1051
1052 data = read_system_page (dat, size_comp, size_uncomp, correction);
1053 if (!data)
1054 {
1055 LOG_ERROR ("Failed to read system page")
1056 return NULL;
1057 }
1058
1059 ptr = data;
1060 ptr_end = data + size_uncomp;
1061
1062 LOG_TRACE ("\n=== System Section (Pages Map) ===\n")
1063
1064 while (ptr < ptr_end)
1065 {
1066 page = (r2007_page *)malloc (sizeof (r2007_page));
1067 if (page == NULL)
1068 {
1069 LOG_ERROR ("Out of memory")
1070 free (data);
1071 pages_destroy (pages);
1072 return NULL;
1073 }
1074 if (ptr + 16 > ptr_end)
1075 {
1076 LOG_ERROR ("Page out of bounds")
1077 free (data);
1078 pages_destroy (pages);
1079 return NULL;
1080 }
1081
1082 page->size = bfr_read_uint64 (ptr);
1083 page->id = bfr_read_int64 (ptr);
1084 page->offset = offset;
1085 offset += page->size;
1086
1087 // index = page->id > 0 ? page->id : -page->id;
1088
1089 LOG_TRACE ("Page [%3" PRId64 "]: ", page->id)
1090 LOG_TRACE ("size: %6" PRIu64 " ", page->size)
1091 LOG_TRACE ("id: 0x%04" PRIx64 " ", page->id)
1092 LOG_TRACE ("offset: 0x%" PRIx64 " \n", page->offset)
1093
1094 page->next = NULL;
1095
1096 if (pages == NULL)
1097 pages = last_page = page;
1098 else
1099 {
1100 last_page->next = page;
1101 last_page = page;
1102 }
1103 }
1104 free (data);
1105 return pages;
1106 }
1107
1108 /* Lookup a page in the page map. The page is identified by its id.
1109 */
1110 static r2007_page *
get_page(r2007_page * pages_map,int64_t id)1111 get_page (r2007_page *pages_map, int64_t id)
1112 {
1113 r2007_page *page = pages_map;
1114
1115 while (page != NULL)
1116 {
1117 if (page->id == id)
1118 break;
1119 page = page->next;
1120 }
1121
1122 return page;
1123 }
1124
1125 static void
pages_destroy(r2007_page * page)1126 pages_destroy (r2007_page *page)
1127 {
1128 r2007_page *next;
1129
1130 while (page != 0)
1131 {
1132 next = page->next;
1133 free (page);
1134 page = next;
1135 }
1136 }
1137
1138 /* Lookup a section in the section map.
1139 * The section is identified by its numeric type.
1140 */
1141 static r2007_section *
get_section(r2007_section * sections_map,Dwg_Section_Type sec_type)1142 get_section (r2007_section *sections_map, Dwg_Section_Type sec_type)
1143 {
1144 r2007_section *section = sections_map;
1145 while (section != NULL)
1146 {
1147 if (section->type == sec_type)
1148 break;
1149 section = section->next;
1150 }
1151
1152 return section;
1153 }
1154
1155 static void
sections_destroy(r2007_section * section)1156 sections_destroy (r2007_section *section)
1157 {
1158 r2007_section *next;
1159
1160 while (section != 0)
1161 {
1162 next = section->next;
1163
1164 if (section->pages)
1165 {
1166 while (section->num_pages-- > 0)
1167 {
1168 free (section->pages[section->num_pages]);
1169 }
1170 free (section->pages);
1171 }
1172
1173 if (section->name)
1174 free (section->name);
1175
1176 free (section);
1177 section = next;
1178 }
1179 }
1180
1181 static int
read_file_header(Bit_Chain * restrict dat,r2007_file_header * restrict file_header)1182 read_file_header (Bit_Chain *restrict dat,
1183 r2007_file_header *restrict file_header)
1184 {
1185 BITCODE_RC data[0x3d8]; // 0x400 - 5 long
1186 BITCODE_RC *pedata;
1187 uint64_t seqence_crc;
1188 uint64_t seqence_key;
1189 uint64_t compr_crc;
1190 int32_t compr_len, len2;
1191 int i;
1192 int error = 0, errcount = 0;
1193 const int pedata_size = 3 * 239; // size of pedata
1194
1195 dat->byte = 0x80;
1196 LOG_TRACE ("\n=== File header ===\n")
1197 memset (file_header, 0, sizeof (r2007_file_header));
1198 memset (data, 0, 0x3d8);
1199 bit_read_fixed (dat, data, 0x3d8);
1200 pedata = decode_rs (data, 3, 239, 0x3d8);
1201 if (!pedata)
1202 return DWG_ERR_OUTOFMEM;
1203
1204 // Note: This is unportable to big-endian
1205 seqence_crc = *((uint64_t *)pedata);
1206 seqence_key = *((uint64_t *)&pedata[8]);
1207 compr_crc = *((uint64_t *)&pedata[16]);
1208 compr_len = *((int32_t *)&pedata[24]);
1209 len2 = *((int32_t *)&pedata[28]);
1210 LOG_TRACE ("seqence_crc64: %016lX\n", (unsigned long)seqence_crc);
1211 LOG_TRACE ("seqence_key: %016lX\n", (unsigned long)seqence_key);
1212 LOG_TRACE ("compr_crc64: %016lX\n", (unsigned long)compr_crc);
1213 LOG_TRACE ("compr_len: %d\n", (int)compr_len); // only this is used
1214 LOG_TRACE ("len2: %d\n", (int)len2); // 0 when compressed
1215
1216 if (compr_len > 0)
1217 error = decompress_r2007 ((BITCODE_RC *)file_header, 0x110, &pedata[32],
1218 MIN (compr_len, pedata_size - 32));
1219 else
1220 memcpy (file_header, &pedata[32], sizeof (r2007_file_header));
1221
1222 // check validity, for debugging only
1223 if (!error)
1224 {
1225
1226 #define VALID_SIZE(var) \
1227 if (var < 0 || (unsigned)var > dat->size) \
1228 { \
1229 errcount++; \
1230 error |= DWG_ERR_VALUEOUTOFBOUNDS; \
1231 LOG_ERROR ("%s Invalid %s %ld > MAX_SIZE", __FUNCTION__, #var, \
1232 (long)var) \
1233 var = 0; \
1234 }
1235 #define VALID_COUNT(var) \
1236 if (var < 0 || (unsigned)var > dat->size) \
1237 { \
1238 errcount++; \
1239 error |= DWG_ERR_VALUEOUTOFBOUNDS; \
1240 LOG_ERROR ("%s Invalid %s %ld > MAX_COUNT", __FUNCTION__, #var, \
1241 (long)var) \
1242 var = 0; \
1243 }
1244
1245 VALID_SIZE (file_header->header_size);
1246 VALID_SIZE (file_header->file_size);
1247 VALID_SIZE (file_header->pages_map_offset);
1248 VALID_SIZE (file_header->header2_offset);
1249 VALID_SIZE (file_header->pages_map_offset);
1250 VALID_SIZE (file_header->pages_map_size_comp);
1251 VALID_SIZE (file_header->pages_map_size_uncomp);
1252 VALID_COUNT (file_header->pages_maxid);
1253 VALID_COUNT (file_header->pages_amount);
1254 VALID_COUNT (file_header->num_sections);
1255 }
1256
1257 free (pedata);
1258 return error;
1259 }
1260
1261 /* Return the latest dat position for all three independent streams
1262 data, handle and string.
1263 */
1264 unsigned long
obj_stream_position(Bit_Chain * restrict dat,Bit_Chain * restrict hdl_dat,Bit_Chain * restrict str_dat)1265 obj_stream_position (Bit_Chain *restrict dat, Bit_Chain *restrict hdl_dat,
1266 Bit_Chain *restrict str_dat)
1267 {
1268 unsigned long p1 = bit_position (dat);
1269 /* all 3 now relative to obj */
1270 unsigned long p2 = bit_position (hdl_dat);
1271 SINCE (R_2007)
1272 { // but only since 2007 there is a seperate string stream
1273 unsigned long p3 = bit_position (str_dat);
1274 if (p2 > p1)
1275 return p3 > p2 ? p3 : p2;
1276 else
1277 return p3 > p1 ? p3 : p1;
1278 }
1279 else
1280 {
1281 return (p2 > p1) ? p2 : p1;
1282 }
1283 }
1284
1285 int
obj_string_stream(Bit_Chain * restrict dat,Dwg_Object * restrict obj,Bit_Chain * restrict str)1286 obj_string_stream (Bit_Chain *restrict dat, Dwg_Object *restrict obj,
1287 Bit_Chain *restrict str)
1288 {
1289 BITCODE_RL start = obj->bitsize - 1; // in bits
1290 BITCODE_RL data_size = 0; // in byte
1291 BITCODE_RL old_size; // in byte
1292 BITCODE_RL old_byte;
1293 //assert (dat != str); // r2007 objects are the same, just entities not
1294 old_size = str->size;
1295 old_byte = str->byte;
1296
1297 //str->chain += str->byte;
1298 //obj->strpos = str->byte * 8 + str->bit;
1299
1300 str->size = (obj->bitsize / 8) + ((obj->bitsize % 8) ? 1 : 0);
1301 bit_set_position (str, start);
1302
1303 if (str->byte >= old_size - old_byte)
1304 {
1305 LOG_ERROR ("obj_string_stream overflow, bitsize " FORMAT_RL " => " FORMAT_RL,
1306 obj->bitsize, obj->size * 8);
1307 str->byte = old_byte;
1308 str->size = old_size;
1309 obj->has_strings = 0;
1310 obj->bitsize = obj->size * 8;
1311 return DWG_ERR_VALUEOUTOFBOUNDS;
1312 }
1313 LOG_HANDLE (" obj string stream +%u: @%lu.%u (%lu)", start, str->byte,
1314 str->bit & 7, bit_position (str));
1315 obj->has_strings = bit_read_B (str);
1316 LOG_TRACE (" has_strings: %d\n", (int)obj->has_strings);
1317 if (!obj->has_strings)
1318 {
1319 // FIXME wrong bit
1320 if (obj->fixedtype == DWG_TYPE_SCALE)
1321 obj->has_strings = 1;
1322 // str->size = 0;
1323 // bit_reset_chain (str);
1324 return 0;
1325 }
1326
1327 bit_advance_position (str, -1); //-17
1328 str->byte -= 2;
1329 LOG_HANDLE (" @%lu.%u", str->byte, str->bit & 7);
1330 data_size = (BITCODE_RL)bit_read_RS (str);
1331 LOG_HANDLE (" data_size: %u/0x%x [RS]", data_size, data_size);
1332
1333 if (data_size & 0x8000)
1334 {
1335 BITCODE_RS hi_size;
1336 str->byte -= 4;
1337 data_size &= 0x7FFF;
1338 LOG_HANDLE (" @%lu.%u", str->byte, str->bit & 7);
1339 hi_size = bit_read_RS (str);
1340 LOG_HANDLE (" hi_size " FORMAT_RS "/" FORMAT_RSx " [RS]", hi_size, hi_size);
1341 data_size |= (hi_size << 15);
1342 LOG_HANDLE (" => data_size: %u/0x%x\n", data_size, data_size);
1343 // LOG_TRACE(" -33: @%lu\n", str->byte);
1344 }
1345 else
1346 LOG_HANDLE ("\n");
1347 str->byte -= 2;
1348 if (data_size > obj->bitsize)
1349 {
1350 LOG_WARN ("Invalid string stream data_size %u > bitsize %u at @%lu.%u\n",
1351 (unsigned)data_size, (unsigned)obj->bitsize, str->byte, str->bit & 7);
1352 if (dat->from_version == R_2007)
1353 {
1354 return 0;
1355 }
1356 obj->has_strings = 0;
1357 bit_reset_chain (str);
1358 return DWG_ERR_NOTYETSUPPORTED; // a very low severity error
1359 }
1360 if (data_size < obj->bitsize)
1361 {
1362 obj->stringstream_size = data_size;
1363 bit_advance_position (str, -(int)data_size);
1364 }
1365 else
1366 {
1367 bit_set_position (str, 0);
1368 }
1369 // bit_reset_chain (str);
1370 // LOG_TRACE(" %d: @%lu.%u (%lu)\n", -(int)data_size - 16, str->byte,
1371 // str->bit & 7,
1372 // bit_position(str));
1373 // obj->strpos = obj->bitsize_pos + obj->bitsize - obj->stringstream_size;
1374 return 0;
1375 }
1376
1377 void
section_string_stream(Dwg_Data * restrict dwg,Bit_Chain * restrict dat,BITCODE_RL bitsize,Bit_Chain * restrict str)1378 section_string_stream (Dwg_Data *restrict dwg, Bit_Chain *restrict dat, BITCODE_RL bitsize,
1379 Bit_Chain *restrict str)
1380 {
1381 BITCODE_RL start; // in bits
1382 BITCODE_RL data_size; // in bits
1383 BITCODE_B endbit;
1384 if (dwg->header.version < R_2010 ||
1385 (dwg->header.version == R_2010 && dwg->header.maint_version < 3))
1386 {
1387 // r2007: + 24 bytes (sentinel+size+hsize) - 1 bit (endbit)
1388 start = bitsize + 159;
1389 }
1390 else
1391 {
1392 // r2010: + 24 bytes (sentinel+size+hSize) - 1 bit (endbit)
1393 start = bitsize + 191; /* 8*24 = 192 */
1394 }
1395 *str = *dat;
1396 bit_set_position (str, start);
1397 LOG_TRACE ("section string stream\n pos: " FORMAT_RL ", %lu/%u\n", start,
1398 str->byte, str->bit);
1399 endbit = bit_read_B (str);
1400 LOG_HANDLE (" endbit: %d\n", (int)endbit);
1401 if (!endbit)
1402 return; // i.e. has no strings. without data_size should be 0
1403 start -= 16;
1404 bit_set_position (str, start);
1405 LOG_HANDLE (" pos: " FORMAT_RL ", %lu\n", start, str->byte);
1406 // str->bit = start & 7;
1407 data_size = bit_read_RS (str);
1408 LOG_HANDLE (" data_size: " FORMAT_RL "\n", data_size);
1409 if (data_size & 0x8000)
1410 {
1411 BITCODE_RS hi_size;
1412 start -= 16;
1413 data_size &= 0x7FFF;
1414 bit_set_position (str, start);
1415 LOG_HANDLE (" pos: " FORMAT_RL ", %lu\n", start, str->byte);
1416 hi_size = bit_read_RS (str);
1417 data_size |= (hi_size << 15);
1418 LOG_HANDLE (" hi_size: " FORMAT_RS ", data_size: " FORMAT_RL "\n",
1419 hi_size, data_size);
1420 }
1421 start -= data_size;
1422 bit_set_position (str, start);
1423 LOG_HANDLE (" pos: " FORMAT_RL ", %lu/%u\n", start, str->byte, str->bit);
1424 }
1425
1426 // for string stream see p86
1427 static int
read_2007_section_classes(Bit_Chain * restrict dat,Dwg_Data * restrict dwg,r2007_section * restrict sections_map,r2007_page * restrict pages_map)1428 read_2007_section_classes (Bit_Chain *restrict dat, Dwg_Data *restrict dwg,
1429 r2007_section *restrict sections_map,
1430 r2007_page *restrict pages_map)
1431 {
1432 BITCODE_RL size, i;
1433 BITCODE_BS max_num;
1434 Bit_Chain sec_dat = { 0 }, str = { 0 };
1435 Dwg_Object *obj = NULL;
1436 int error;
1437 char c;
1438
1439 error = read_data_section (&sec_dat, dat, sections_map, pages_map,
1440 SECTION_CLASSES);
1441 if (error)
1442 {
1443 LOG_ERROR ("Failed to read class section");
1444 if (sec_dat.chain)
1445 free (sec_dat.chain);
1446 return error;
1447 }
1448
1449 if (bit_search_sentinel (&sec_dat, dwg_sentinel (DWG_SENTINEL_CLASS_BEGIN)))
1450 {
1451 BITCODE_RL bitsize = 0;
1452 LOG_TRACE ("\nClasses\n-------------------\n")
1453 size = bit_read_RL (&sec_dat); // size of class data area
1454 LOG_TRACE ("size: " FORMAT_RL " [RL]\n", size)
1455 /*
1456 if (dat->from_version >= R_2010 && dwg->header.maint_version > 3)
1457 {
1458 BITCODE_RL hsize = bit_read_RL(&sec_dat);
1459 LOG_TRACE("hsize: " FORMAT_RL " [RL]\n", hsize)
1460 }
1461 */
1462 if (dat->from_version >= R_2007)
1463 {
1464 bitsize = bit_read_RL (&sec_dat);
1465 LOG_TRACE ("bitsize: " FORMAT_RL " [RL]\n", bitsize)
1466 }
1467 max_num = bit_read_BS (&sec_dat); // Maximum class number
1468 LOG_TRACE ("max_num: " FORMAT_BS " [BS]\n", max_num)
1469 c = bit_read_RC (&sec_dat); // 0x00
1470 LOG_HANDLE ("c: " FORMAT_RC " [RC]\n", c)
1471 c = bit_read_RC (&sec_dat); // 0x00
1472 LOG_HANDLE ("c: " FORMAT_RC " [RC]\n", c)
1473 c = bit_read_B (&sec_dat); // 1
1474 LOG_HANDLE ("c: " FORMAT_B " [B]\n", c);
1475
1476 dwg->layout_type = 0;
1477 dwg->num_classes = max_num - 499;
1478 if (max_num < 500 || max_num > 5000)
1479 {
1480 LOG_ERROR ("Invalid max class number %d", max_num)
1481 dwg->num_classes = 0;
1482 if (sec_dat.chain)
1483 free (sec_dat.chain);
1484 return DWG_ERR_VALUEOUTOFBOUNDS;
1485 }
1486 assert (max_num >= 500);
1487 assert (max_num < 5000);
1488
1489 section_string_stream (dwg, &sec_dat, bitsize, &str);
1490
1491 dwg->dwg_class
1492 = (Dwg_Class *)calloc (dwg->num_classes, sizeof (Dwg_Class));
1493 if (!dwg->dwg_class)
1494 {
1495 LOG_ERROR ("Out of memory");
1496 if (sec_dat.chain)
1497 free (sec_dat.chain);
1498 return DWG_ERR_OUTOFMEM;
1499 }
1500
1501 for (i = 0; i < dwg->num_classes; i++)
1502 {
1503 dwg->dwg_class[i].number = bit_read_BS (&sec_dat);
1504 dwg->dwg_class[i].proxyflag = bit_read_BS (&sec_dat);
1505 dwg->dwg_class[i].appname = (char *)bit_read_TU (&str);
1506 dwg->dwg_class[i].cppname = (char *)bit_read_TU (&str);
1507 dwg->dwg_class[i].dxfname_u = bit_read_TU (&str);
1508 dwg->dwg_class[i].is_zombie = bit_read_B (&sec_dat); // DXF 280
1509 dwg->dwg_class[i].item_class_id = bit_read_BS (&sec_dat); // DXF 281, is_entity is 0x1f3
1510
1511 dwg->dwg_class[i].num_instances = bit_read_BL (&sec_dat); // DXF 91
1512 dwg->dwg_class[i].dwg_version = bit_read_BS (&sec_dat);
1513 dwg->dwg_class[i].maint_version = bit_read_BS (&sec_dat);
1514 dwg->dwg_class[i].unknown_1 = bit_read_BL (&sec_dat); // 0
1515 dwg->dwg_class[i].unknown_2 = bit_read_BL (&sec_dat); // 0
1516
1517 LOG_TRACE ("-------------------\n")
1518 LOG_TRACE ("Number: %d\n", dwg->dwg_class[i].number)
1519 LOG_TRACE ("Proxyflag: 0x%x\n", dwg->dwg_class[i].proxyflag)
1520 LOG_TRACE_TU ("Application name", dwg->dwg_class[i].appname, 0)
1521 LOG_TRACE_TU ("C++ class name ", dwg->dwg_class[i].cppname, 0)
1522 LOG_TRACE_TU ("DXF record name ", dwg->dwg_class[i].dxfname_u, 0)
1523 LOG_TRACE ("Class ID: 0x%x "
1524 "(0x1f3 for object, 0x1f2 for entity)\n",
1525 dwg->dwg_class[i].item_class_id)
1526 LOG_TRACE ("instance count: %u\n", dwg->dwg_class[i].num_instances)
1527 LOG_TRACE ("dwg version: %u (%u)\n",
1528 dwg->dwg_class[i].dwg_version,
1529 dwg->dwg_class[i].maint_version)
1530 LOG_HANDLE ("unknown: %u %u\n", dwg->dwg_class[i].unknown_1,
1531 dwg->dwg_class[i].unknown_2)
1532
1533 dwg->dwg_class[i].dxfname
1534 = bit_convert_TU (dwg->dwg_class[i].dxfname_u);
1535 if (dwg->dwg_class[i].dxfname
1536 && strEQc (dwg->dwg_class[i].dxfname, "LAYOUT"))
1537 dwg->layout_type = dwg->dwg_class[i].number;
1538 }
1539 }
1540 else
1541 {
1542 LOG_ERROR ("Failed to find class section sentinel");
1543 free (sec_dat.chain);
1544 return DWG_ERR_CLASSESNOTFOUND;
1545 }
1546
1547 if (sec_dat.chain)
1548 free (sec_dat.chain);
1549
1550 return 0;
1551 }
1552
1553 static int
read_2007_section_header(Bit_Chain * restrict dat,Bit_Chain * restrict hdl_dat,Dwg_Data * restrict dwg,r2007_section * restrict sections_map,r2007_page * restrict pages_map)1554 read_2007_section_header (Bit_Chain *restrict dat, Bit_Chain *restrict hdl_dat,
1555 Dwg_Data *restrict dwg,
1556 r2007_section *restrict sections_map,
1557 r2007_page *restrict pages_map)
1558 {
1559 Bit_Chain sec_dat = { 0 }, str_dat = { 0 };
1560 int error;
1561 LOG_TRACE ("\nSection Header\n-------------------\n");
1562 error = read_data_section (&sec_dat, dat, sections_map, pages_map,
1563 SECTION_HEADER);
1564 if (error)
1565 {
1566 LOG_ERROR ("Failed to read header section");
1567 if (sec_dat.chain)
1568 free (sec_dat.chain);
1569 return error;
1570 }
1571 if (bit_search_sentinel (&sec_dat,
1572 dwg_sentinel (DWG_SENTINEL_VARIABLE_BEGIN)))
1573 {
1574 BITCODE_RL endbits = 160; // start bit: 16 sentinel + 4 size
1575 dwg->header_vars.size = bit_read_RL (&sec_dat);
1576 LOG_TRACE ("size: " FORMAT_RL "\n", dwg->header_vars.size);
1577 *hdl_dat = sec_dat;
1578 // unused: later versions re-use the 2004 section format
1579 /*
1580 if (dat->from_version >= R_2010 && dwg->header.maint_version > 3)
1581 {
1582 dwg->header_vars.bitsize_hi = bit_read_RL(&sec_dat);
1583 LOG_TRACE("bitsize_hi: " FORMAT_RL " [RL]\n",
1584 dwg->header_vars.bitsize_hi) endbits += 32;
1585 }
1586 */
1587 if (dat->from_version == R_2007) // always true so far
1588 {
1589 dwg->header_vars.bitsize = bit_read_RL (&sec_dat);
1590 LOG_TRACE ("bitsize: " FORMAT_RL " [RL]\n",
1591 dwg->header_vars.bitsize);
1592 endbits += dwg->header_vars.bitsize;
1593 bit_set_position (hdl_dat, endbits);
1594 section_string_stream (dwg, &sec_dat, dwg->header_vars.bitsize, &str_dat);
1595 }
1596
1597 dwg_decode_header_variables (&sec_dat, hdl_dat, &str_dat, dwg);
1598 }
1599 else
1600 {
1601 DEBUG_HERE;
1602 error = DWG_ERR_SECTIONNOTFOUND;
1603 }
1604
1605 if (sec_dat.chain)
1606 free (sec_dat.chain);
1607
1608 return error;
1609 }
1610
1611 static int
read_2007_section_handles(Bit_Chain * dat,Bit_Chain * hdl,Dwg_Data * restrict dwg,r2007_section * restrict sections_map,r2007_page * restrict pages_map)1612 read_2007_section_handles (Bit_Chain *dat, Bit_Chain *hdl,
1613 Dwg_Data *restrict dwg,
1614 r2007_section *restrict sections_map,
1615 r2007_page *restrict pages_map)
1616 {
1617 static Bit_Chain obj_dat = { 0 }, hdl_dat = { 0 };
1618 BITCODE_RS section_size = 0;
1619 long unsigned int endpos;
1620 int error;
1621
1622 error = read_data_section (&obj_dat, dat, sections_map, pages_map,
1623 SECTION_OBJECTS);
1624 if (error >= DWG_ERR_CRITICAL || !obj_dat.chain)
1625 {
1626 LOG_ERROR ("Failed to read objects section");
1627 if (obj_dat.chain)
1628 free (obj_dat.chain);
1629 return error;
1630 }
1631
1632 LOG_TRACE ("\nHandles\n-------------------\n")
1633 error = read_data_section (&hdl_dat, dat, sections_map, pages_map,
1634 SECTION_HANDLES);
1635 if (error >= DWG_ERR_CRITICAL|| !hdl_dat.chain)
1636 {
1637 LOG_ERROR ("Failed to read handles section");
1638 if (obj_dat.chain)
1639 free (obj_dat.chain);
1640 if (hdl_dat.chain)
1641 free (hdl_dat.chain);
1642 return error;
1643 }
1644
1645 /* From here on the same code as in decode:read_2004_section_handles */
1646 endpos = hdl_dat.byte + hdl_dat.size;
1647 dwg->num_objects = 0;
1648
1649 do
1650 {
1651 long unsigned int last_offset;
1652 // long unsigned int last_handle;
1653 long unsigned int oldpos = 0;
1654 long unsigned int startpos = hdl_dat.byte;
1655 uint16_t crc1, crc2;
1656
1657 section_size = bit_read_RS_LE (&hdl_dat);
1658 LOG_TRACE ("\nSection size: %u\n", section_size);
1659 if (section_size > 2050)
1660 {
1661 LOG_ERROR ("Object-map/handles section size greater than 2050!");
1662 return DWG_ERR_VALUEOUTOFBOUNDS;
1663 }
1664
1665 last_offset = 0;
1666 while ((long)(hdl_dat.byte - startpos) < (long)section_size)
1667 {
1668 int added;
1669 BITCODE_UMC handleoff;
1670 BITCODE_MC offset;
1671
1672 oldpos = hdl_dat.byte;
1673 handleoff = bit_read_UMC (&hdl_dat);
1674 offset = bit_read_MC (&hdl_dat);
1675 last_offset += offset;
1676 LOG_TRACE ("\nNext object: %lu ", (unsigned long)dwg->num_objects)
1677 LOG_TRACE ("Handleoff: " FORMAT_MC " [UMC] "
1678 "Offset: " FORMAT_MC " [MC] @%lu\n",
1679 handleoff, offset, last_offset)
1680
1681 if (hdl_dat.byte == oldpos)
1682 break;
1683
1684 added = dwg_decode_add_object (dwg, &obj_dat, hdl, last_offset);
1685 if (added > 0)
1686 error |= added;
1687 }
1688
1689 if (hdl_dat.byte == oldpos)
1690 break;
1691 #if 0
1692 if (!bit_check_CRC(&hdl_dat, startpos, 0xC0C1))
1693 LOG_WARN("Handles section CRC mismatch at offset %lx", startpos);
1694 #else
1695 crc1 = bit_calc_CRC (0xC0C1, &(hdl_dat.chain[startpos]),
1696 hdl_dat.byte - startpos);
1697 crc2 = bit_read_RS_LE (&hdl_dat);
1698 if (crc1 == crc2)
1699 {
1700 LOG_INSANE ("Handles section page CRC: %04X from %lx-%lx\n", crc2,
1701 startpos, hdl_dat.byte - 2);
1702 }
1703 else
1704 {
1705 LOG_WARN ("Handles section page CRC mismatch: %04X vs calc. %04X "
1706 "from %lx-%lx\n",
1707 crc2, crc1, startpos, hdl_dat.byte - 2);
1708 error |= DWG_ERR_WRONGCRC;
1709 }
1710 #endif
1711
1712 if (hdl_dat.byte >= endpos)
1713 break;
1714 }
1715 while (section_size > 2);
1716
1717 if (hdl_dat.chain)
1718 free (hdl_dat.chain);
1719 if (obj_dat.chain)
1720 free (obj_dat.chain);
1721 return error;
1722 }
1723
1724 /* VBAProject Section
1725 */
1726 static int
read_2007_section_vbaproject(Bit_Chain * restrict dat,Dwg_Data * restrict dwg,r2007_section * restrict sections_map,r2007_page * restrict pages_map)1727 read_2007_section_vbaproject (Bit_Chain *restrict dat, Dwg_Data *restrict dwg,
1728 r2007_section *restrict sections_map,
1729 r2007_page *restrict pages_map)
1730 {
1731 Bit_Chain old_dat, sec_dat = { 0 };
1732 //Bit_Chain *str_dat;
1733 Dwg_VBAProject *_obj = &dwg->vbaproject;
1734 Dwg_Object *obj = NULL;
1735 int error = 0;
1736 //BITCODE_RL rcount1 = 0, rcount2 = 0;
1737
1738 // not compressed, page size: 0x80
1739 error = read_data_section (&sec_dat, dat, sections_map, pages_map,
1740 SECTION_VBAPROJECT);
1741 if (error >= DWG_ERR_CRITICAL || !sec_dat.chain)
1742 {
1743 LOG_INFO ("%s section not found\n", "VBAProject");
1744 if (sec_dat.chain)
1745 free (sec_dat.chain);
1746 return error;
1747 }
1748
1749 LOG_TRACE ("\nVBAProject (%lu)\n-------------------\n", sec_dat.size)
1750 old_dat = *dat;
1751 dat = &sec_dat; // restrict in size
1752 bit_chain_set_version (&old_dat, dat);
1753
1754 DEBUG_HERE
1755 _obj->size = dat->size;
1756 _obj->unknown_bits = bit_read_TF (dat, _obj->size);
1757 LOG_TRACE_TF (_obj->unknown_bits, _obj->size)
1758
1759 LOG_TRACE ("\n")
1760 if (sec_dat.chain)
1761 free (sec_dat.chain);
1762 *dat = old_dat; // unrestrict
1763 return error;
1764 }
1765
1766 static int
read_2007_section_summary(Bit_Chain * restrict dat,Dwg_Data * restrict dwg,r2007_section * restrict sections_map,r2007_page * restrict pages_map)1767 read_2007_section_summary (Bit_Chain *restrict dat, Dwg_Data *restrict dwg,
1768 r2007_section *restrict sections_map,
1769 r2007_page *restrict pages_map)
1770 {
1771 static Bit_Chain old_dat, sec_dat = { 0 };
1772 Bit_Chain *str_dat;
1773 Dwg_SummaryInfo *_obj = &dwg->summaryinfo;
1774 Dwg_Object *obj = NULL;
1775 int error;
1776 BITCODE_RL rcount1 = 0, rcount2 = 0;
1777
1778 old_dat = *dat;
1779 error = read_data_section (&sec_dat, dat, sections_map, pages_map,
1780 SECTION_SUMMARYINFO);
1781 if (error >= DWG_ERR_CRITICAL || !sec_dat.chain)
1782 {
1783 LOG_ERROR ("Failed to read SummaryInfo section");
1784 if (sec_dat.chain)
1785 free (sec_dat.chain);
1786 return error;
1787 }
1788
1789 if (dwg->header.summaryinfo_address != (BITCODE_RL)dat->byte)
1790 LOG_WARN ("summaryinfo_address mismatch: " FORMAT_RL " != %lu",
1791 dwg->header.summaryinfo_address, dat->byte);
1792 LOG_TRACE ("\nSummaryInfo (%lu)\n-------------------\n", sec_dat.size)
1793 str_dat = dat = &sec_dat; // restrict in size
1794 bit_chain_set_version (&old_dat, dat);
1795
1796 // clang-format off
1797 #include "summaryinfo.spec"
1798 // clang-format on
1799
1800 if (sec_dat.chain)
1801 free (sec_dat.chain);
1802 *dat = old_dat; // unrestrict
1803 return error;
1804 }
1805
1806 /* AppInfo Section
1807 */
1808 static int
read_2007_section_appinfo(Bit_Chain * restrict dat,Dwg_Data * restrict dwg,r2007_section * restrict sections_map,r2007_page * restrict pages_map)1809 read_2007_section_appinfo (Bit_Chain *restrict dat, Dwg_Data *restrict dwg,
1810 r2007_section *restrict sections_map,
1811 r2007_page *restrict pages_map)
1812 {
1813 Bit_Chain old_dat, sec_dat = { 0 };
1814 Bit_Chain *str_dat;
1815 Dwg_AppInfo *_obj = &dwg->appinfo;
1816 Dwg_Object *obj = NULL;
1817 int error = 0;
1818 BITCODE_RL rcount1 = 0, rcount2 = 0;
1819
1820 // not compressed, page size: 0x80
1821 error = read_data_section (&sec_dat, dat, sections_map, pages_map,
1822 SECTION_APPINFO);
1823 if (error >= DWG_ERR_CRITICAL || !sec_dat.chain)
1824 {
1825 LOG_INFO ("%s section not found\n", "AppInfo");
1826 if (sec_dat.chain)
1827 free (sec_dat.chain);
1828 return error;
1829 }
1830
1831 LOG_TRACE ("\nAppInfo (%lu)\n-------------------\n", sec_dat.size)
1832 old_dat = *dat;
1833 str_dat = dat = &sec_dat; // restrict in size
1834 bit_chain_set_version (&old_dat, dat);
1835
1836 // clang-format off
1837 #include "appinfo.spec"
1838 // clang-format on
1839
1840 LOG_TRACE ("\n")
1841 if (sec_dat.chain)
1842 free (sec_dat.chain);
1843 *dat = old_dat; // unrestrict
1844 return error;
1845 }
1846
1847 /* AuxHeader Section
1848 */
1849 static int
read_2007_section_auxheader(Bit_Chain * restrict dat,Dwg_Data * restrict dwg,r2007_section * restrict sections_map,r2007_page * restrict pages_map)1850 read_2007_section_auxheader (Bit_Chain *restrict dat, Dwg_Data *restrict dwg,
1851 r2007_section *restrict sections_map,
1852 r2007_page *restrict pages_map)
1853 {
1854 Bit_Chain old_dat, sec_dat = { 0 };
1855 //Bit_Chain *str_dat;
1856 Dwg_AuxHeader *_obj = &dwg->auxheader;
1857 Dwg_Object *obj = NULL;
1858 int error = 0;
1859 BITCODE_RL vcount = 0, rcount1 = 0, rcount2 = 0;
1860
1861 // type: 2, compressed, page size: 0x7400
1862 error = read_data_section (&sec_dat, dat, sections_map, pages_map,
1863 SECTION_AUXHEADER);
1864 if (error >= DWG_ERR_CRITICAL || !sec_dat.chain)
1865 {
1866 LOG_INFO ("%s section not found\n", "AuxHeader");
1867 if (sec_dat.chain)
1868 free (sec_dat.chain);
1869 return error;
1870 }
1871
1872 LOG_TRACE ("\nAuxHeader (%lu)\n-------------------\n", sec_dat.size)
1873 old_dat = *dat;
1874 dat = &sec_dat; // restrict in size
1875 bit_chain_set_version (&old_dat, dat);
1876
1877 // clang-format off
1878 #include "auxheader.spec"
1879 // clang-format on
1880
1881 LOG_TRACE ("\n")
1882 if (sec_dat.chain)
1883 free (sec_dat.chain);
1884 *dat = old_dat; // unrestrict
1885 return error;
1886 }
1887
1888 /* Unknown AppInfoHistory Section
1889 */
1890 static int
read_2007_section_appinfohistory(Bit_Chain * restrict dat,Dwg_Data * restrict dwg,r2007_section * restrict sections_map,r2007_page * restrict pages_map)1891 read_2007_section_appinfohistory (Bit_Chain *restrict dat, Dwg_Data *restrict dwg,
1892 r2007_section *restrict sections_map,
1893 r2007_page *restrict pages_map)
1894 {
1895 Bit_Chain old_dat, sec_dat = { 0 };
1896 //Bit_Chain *str_dat;
1897 Dwg_AppInfoHistory *_obj = &dwg->appinfohistory;
1898 Dwg_Object *obj = NULL;
1899 int error = 0;
1900 //BITCODE_RL rcount1 = 0, rcount2 = 0;
1901
1902 // compressed, page size: 0x580
1903 error = read_data_section (&sec_dat, dat, sections_map, pages_map,
1904 SECTION_APPINFOHISTORY);
1905 if (error >= DWG_ERR_CRITICAL || !sec_dat.chain)
1906 {
1907 LOG_INFO ("%s section not found\n", "AppInfoHistory");
1908 if (sec_dat.chain)
1909 free (sec_dat.chain);
1910 return error;
1911 }
1912
1913 LOG_TRACE ("\nAppInfoHistory (%lu)\n-------------------\n", sec_dat.size)
1914 old_dat = *dat;
1915 dat = &sec_dat; // restrict in size
1916 bit_chain_set_version (&old_dat, dat);
1917
1918 DEBUG_HERE
1919 _obj->size = dat->size;
1920 _obj->unknown_bits = bit_read_TF (dat, _obj->size);
1921 LOG_TRACE_TF (_obj->unknown_bits, _obj->size)
1922
1923 LOG_TRACE ("\n")
1924 if (sec_dat.chain)
1925 free (sec_dat.chain);
1926 *dat = old_dat; // unrestrict
1927 return error;
1928 }
1929
1930 /* RevHistory Section
1931 */
1932 static int
read_2007_section_revhistory(Bit_Chain * restrict dat,Dwg_Data * restrict dwg,r2007_section * restrict sections_map,r2007_page * restrict pages_map)1933 read_2007_section_revhistory (Bit_Chain *restrict dat, Dwg_Data *restrict dwg,
1934 r2007_section *restrict sections_map,
1935 r2007_page *restrict pages_map)
1936 {
1937 Bit_Chain old_dat, sec_dat = { 0 };
1938 //Bit_Chain *str_dat;
1939 Dwg_RevHistory *_obj = &dwg->revhistory;
1940 Dwg_Object *obj = NULL;
1941 int error = 0;
1942 BITCODE_RL rcount1 = 0, rcount2 = 0;
1943
1944 // compressed, page size: 0x7400
1945 error = read_data_section (&sec_dat, dat, sections_map, pages_map,
1946 SECTION_REVHISTORY);
1947 if (error >= DWG_ERR_CRITICAL || !sec_dat.chain)
1948 {
1949 LOG_INFO ("%s section not found\n", "RevHistory");
1950 if (sec_dat.chain)
1951 free (sec_dat.chain);
1952 return error;
1953 }
1954
1955 LOG_TRACE ("\nRevHistory (%lu)\n-------------------\n", sec_dat.size)
1956 old_dat = *dat;
1957 dat = &sec_dat; // restrict in size
1958 bit_chain_set_version (&old_dat, dat);
1959
1960 // clang-format off
1961 #include "revhistory.spec"
1962 // clang-format on
1963
1964 LOG_TRACE ("\n")
1965 if (sec_dat.chain)
1966 free (sec_dat.chain);
1967 *dat = old_dat; // unrestrict
1968 return error;
1969 }
1970
1971 /* ObjFreeSpace Section
1972 */
1973 static int
read_2007_section_objfreespace(Bit_Chain * restrict dat,Dwg_Data * restrict dwg,r2007_section * restrict sections_map,r2007_page * restrict pages_map)1974 read_2007_section_objfreespace (Bit_Chain *restrict dat, Dwg_Data *restrict dwg,
1975 r2007_section *restrict sections_map,
1976 r2007_page *restrict pages_map)
1977 {
1978 Bit_Chain old_dat, sec_dat = { 0 };
1979 //Bit_Chain *str_dat;
1980 Dwg_ObjFreeSpace *_obj = &dwg->objfreespace;
1981 Dwg_Object *obj = NULL;
1982 int error = 0;
1983 BITCODE_RL rcount1 = 0, rcount2 = 0;
1984
1985 // compressed, page size: 0x7400
1986 error = read_data_section (&sec_dat, dat, sections_map, pages_map,
1987 SECTION_OBJFREESPACE);
1988 if (error >= DWG_ERR_CRITICAL || !sec_dat.chain)
1989 {
1990 LOG_INFO ("%s section not found\n", "ObjFreeSpace");
1991 if (sec_dat.chain)
1992 free (sec_dat.chain);
1993 return error;
1994 }
1995
1996 LOG_TRACE ("\nObjFreeSpace (%lu)\n-------------------\n", sec_dat.size)
1997 old_dat = *dat;
1998 dat = &sec_dat; // restrict in size
1999 bit_chain_set_version (&old_dat, dat);
2000
2001 // clang-format off
2002 #include "objfreespace.spec"
2003 // clang-format on
2004
2005 LOG_TRACE ("\n")
2006 if (sec_dat.chain)
2007 free (sec_dat.chain);
2008 *dat = old_dat; // unrestrict
2009 return error;
2010 }
2011
2012 /* Template Section. Optional r13-r15, mandatory r18+.
2013 Contains the MEASUREMENT variable (0 = English, 1 = Metric).
2014 */
2015 static int
read_2007_section_template(Bit_Chain * restrict dat,Dwg_Data * restrict dwg,r2007_section * restrict sections_map,r2007_page * restrict pages_map)2016 read_2007_section_template (Bit_Chain *restrict dat, Dwg_Data *restrict dwg,
2017 r2007_section *restrict sections_map,
2018 r2007_page *restrict pages_map)
2019 {
2020 Bit_Chain old_dat, sec_dat = { 0 };
2021 //Bit_Chain *str_dat;
2022 Dwg_Template *_obj = &dwg->Template;
2023 Dwg_Object *obj = NULL;
2024 int error = 0;
2025 BITCODE_RL rcount1 = 0, rcount2 = 0;
2026
2027 // compressed
2028 error = read_data_section (&sec_dat, dat, sections_map, pages_map,
2029 SECTION_TEMPLATE);
2030 if (error >= DWG_ERR_CRITICAL || !sec_dat.chain)
2031 {
2032 LOG_ERROR ("%s section not found\n", "Template");
2033 if (sec_dat.chain)
2034 free (sec_dat.chain);
2035 return error | DWG_ERR_SECTIONNOTFOUND;
2036 }
2037
2038 LOG_TRACE ("\nTemplate (%lu)\n-------------------\n", sec_dat.size)
2039 old_dat = *dat;
2040 dat = &sec_dat; // restrict in size
2041 bit_chain_set_version (&old_dat, dat);
2042
2043 // clang-format off
2044 #include "template.spec"
2045 // clang-format on
2046
2047 dwg->header_vars.MEASUREMENT = _obj->MEASUREMENT;
2048 LOG_TRACE ("HEADER.MEASUREMENT: " FORMAT_BS " (0 English/1 Metric)\n",
2049 dwg->header_vars.MEASUREMENT)
2050
2051 LOG_TRACE ("\n")
2052 if (sec_dat.chain)
2053 free (sec_dat.chain);
2054 *dat = old_dat; // unrestrict
2055 return error;
2056 }
2057
2058 /* r21 FileDepList Section
2059 */
2060 static int
read_2007_section_filedeplist(Bit_Chain * restrict dat,Dwg_Data * restrict dwg,r2007_section * restrict sections_map,r2007_page * restrict pages_map)2061 read_2007_section_filedeplist (Bit_Chain *restrict dat, Dwg_Data *restrict dwg,
2062 r2007_section *restrict sections_map,
2063 r2007_page *restrict pages_map)
2064 {
2065 Bit_Chain old_dat, sec_dat = { 0 };
2066 int error;
2067 Bit_Chain *str_dat;
2068 Dwg_FileDepList *_obj = &dwg->filedeplist;
2069 Dwg_Object *obj = NULL;
2070 BITCODE_BL vcount;
2071 BITCODE_RL rcount1 = 0, rcount2 = 0;
2072
2073 // not compressed, page size: 0x80. 0xc or 0xd
2074 error = read_data_section (&sec_dat, dat, sections_map, pages_map,
2075 SECTION_FILEDEPLIST);
2076 if (error >= DWG_ERR_CRITICAL || !sec_dat.chain)
2077 {
2078 LOG_INFO ("%s section not found\n", "FileDepList");
2079 if (sec_dat.chain)
2080 free (sec_dat.chain);
2081 return 0;
2082 }
2083
2084 LOG_TRACE ("FileDepList (%lu)\n-------------------\n", sec_dat.size)
2085 old_dat = *dat;
2086 str_dat = dat = &sec_dat; // restrict in size
2087 bit_chain_set_version (&old_dat, dat);
2088
2089 // clang-format off
2090 #include "filedeplist.spec"
2091 // clang-format on
2092
2093 LOG_TRACE ("\n")
2094 if (sec_dat.chain)
2095 free (sec_dat.chain);
2096 *dat = old_dat; // unrestrict
2097 return error;
2098 }
2099
2100 /* r21 Security Section, if saved with password
2101 */
2102 static int
read_2007_section_security(Bit_Chain * restrict dat,Dwg_Data * restrict dwg,r2007_section * restrict sections_map,r2007_page * restrict pages_map)2103 read_2007_section_security (Bit_Chain *restrict dat, Dwg_Data *restrict dwg,
2104 r2007_section *restrict sections_map,
2105 r2007_page *restrict pages_map)
2106 {
2107 Bit_Chain old_dat, sec_dat = { 0 };
2108 int error;
2109 Bit_Chain *str_dat;
2110 Dwg_Security *_obj = &dwg->security;
2111 Dwg_Object *obj = NULL;
2112 BITCODE_RL rcount1 = 0, rcount2 = 0;
2113
2114 // compressed, page size: 0x7400
2115 error = read_data_section (&sec_dat, dat, sections_map, pages_map,
2116 SECTION_SECURITY);
2117 if (error >= DWG_ERR_CRITICAL || !sec_dat.chain)
2118 {
2119 LOG_INFO ("%s section not found\n", "Security");
2120 if (sec_dat.chain)
2121 free (sec_dat.chain);
2122 return 0;
2123 }
2124
2125 LOG_TRACE ("Security (%lu)\n-------------------\n", sec_dat.size)
2126 old_dat = *dat;
2127 str_dat = dat = &sec_dat; // restrict in size
2128 bit_chain_set_version (&old_dat, dat);
2129
2130 // clang-format off
2131 #include "security.spec"
2132 // clang-format on
2133
2134 LOG_TRACE ("\n")
2135 if (sec_dat.chain)
2136 free (sec_dat.chain);
2137 *dat = old_dat; // unrestrict
2138 return error;
2139 }
2140
2141 #if 0
2142 /* Signature Section, not written nor documented by Teigha
2143 */
2144 static int
2145 read_2007_section_signature (Bit_Chain *restrict dat, Dwg_Data *restrict dwg,
2146 r2007_section *restrict sections_map,
2147 r2007_page *restrict pages_map)
2148 {
2149 Bit_Chain old_dat, sec_dat = { 0 };
2150 int error;
2151 Bit_Chain *str_dat;
2152 struct Dwg_Signature *_obj = &dwg->signature;
2153 Dwg_Object *obj = NULL;
2154 BITCODE_RL rcount1 = 0, rcount2 = 0;
2155
2156 // compressed, page size: 0x7400
2157 error = read_data_section (&sec_dat, dat, sections_map, pages_map,
2158 SECTION_SIGNATURE);
2159 if (error >= DWG_ERR_CRITICAL || !sec_dat.chain)
2160 {
2161 LOG_INFO ("%s section not found\n", "Signature");
2162 if (sec_dat.chain)
2163 free (sec_dat.chain);
2164 return 0;
2165 }
2166
2167 LOG_TRACE ("Signature (%lu)\n-------------------\n", sec_dat.size)
2168 old_dat = *dat;
2169 str_dat = dat = &sec_dat; // restrict in size
2170 bit_chain_set_version (&old_dat, dat);
2171
2172 // clang-format off
2173 #include "signature.spec"
2174 // clang-format on
2175
2176 LOG_TRACE ("\n")
2177 if (sec_dat.chain)
2178 free (sec_dat.chain);
2179 *dat = old_dat; // unrestrict
2180 return error;
2181 }
2182 #endif
2183
2184 static int
acds_private(Bit_Chain * restrict dat,Dwg_Data * restrict dwg)2185 acds_private (Bit_Chain *restrict dat, Dwg_Data *restrict dwg)
2186 {
2187 Bit_Chain *str_dat = dat;
2188 Dwg_AcDs *_obj = &dwg->acds;
2189 Dwg_Object *obj = NULL;
2190 int error = 0;
2191 BITCODE_BL rcount1 = 0, rcount2 = 0;
2192 BITCODE_BL rcount3 = 0, rcount4, vcount;
2193
2194 // clang-format off
2195 #include "acds.spec"
2196 // clang-format on
2197
2198 return error;
2199 }
2200
2201 /* r2013+ datastorage Section, if saved with binary ACIS SAB data
2202 */
2203 static int
read_2007_section_acds(Bit_Chain * restrict dat,Dwg_Data * restrict dwg,r2007_section * restrict sections_map,r2007_page * restrict pages_map)2204 read_2007_section_acds (Bit_Chain *restrict dat, Dwg_Data *restrict dwg,
2205 r2007_section *restrict sections_map,
2206 r2007_page *restrict pages_map)
2207 {
2208 Bit_Chain old_dat, sec_dat = { 0 };
2209 int error;
2210 Bit_Chain *str_dat;
2211 const char *secname = "AcDsPrototype_1b";
2212 Dwg_AcDs *_obj = &dwg->acds;
2213 Dwg_Object *obj = NULL;
2214 BITCODE_RL rcount1 = 0, rcount2 = 0;
2215
2216 // compressed, pagesize 0x7400, type 13
2217 error = read_data_section (&sec_dat, dat, sections_map, pages_map, SECTION_ACDS);
2218 if (error >= DWG_ERR_CRITICAL || !sec_dat.chain)
2219 {
2220 LOG_INFO ("%s section not found\n", secname);
2221 if (sec_dat.chain)
2222 free (sec_dat.chain);
2223 return 0;
2224 }
2225
2226 LOG_TRACE ("AcDs datastorage (%lu)\n-------------------\n", sec_dat.size)
2227 old_dat = *dat;
2228 str_dat = dat = &sec_dat; // restrict in size
2229 bit_chain_set_version (&old_dat, dat);
2230
2231 error |= acds_private (dat, dwg);
2232 error &= ~DWG_ERR_SECTIONNOTFOUND;
2233
2234 LOG_TRACE ("\n")
2235 if (sec_dat.chain)
2236 free (sec_dat.chain);
2237 *dat = old_dat; // unrestrict
2238 return error;
2239 }
2240
2241 static int
read_2007_section_preview(Bit_Chain * restrict dat,Dwg_Data * restrict dwg,r2007_section * restrict sections_map,r2007_page * restrict pages_map)2242 read_2007_section_preview (Bit_Chain *restrict dat, Dwg_Data *restrict dwg,
2243 r2007_section *restrict sections_map,
2244 r2007_page *restrict pages_map)
2245 {
2246 static Bit_Chain sec_dat = { 0 };
2247 int error;
2248 BITCODE_RL size;
2249 unsigned char *sentinel;
2250
2251 error = read_data_section (&sec_dat, dat, sections_map, pages_map,
2252 SECTION_PREVIEW);
2253 if (error >= DWG_ERR_CRITICAL || !sec_dat.chain)
2254 {
2255 LOG_ERROR ("Failed to read uncompressed %s section", "Preview");
2256 if (sec_dat.chain)
2257 free (sec_dat.chain);
2258 return error;
2259 }
2260
2261 if (dwg->header.thumbnail_address != (BITCODE_RL)dat->byte)
2262 LOG_WARN ("thumbnail_address mismatch: " FORMAT_RL " != %lu",
2263 dwg->header.thumbnail_address, dat->byte);
2264 LOG_TRACE ("\nPreview (%lu)\n-------------------\n", sec_dat.size)
2265 if (!sec_dat.chain || sec_dat.size < 32)
2266 {
2267 LOG_WARN ("Empty thumbnail");
2268 if (sec_dat.chain)
2269 free (sec_dat.chain);
2270 return error;
2271 }
2272
2273 sentinel = dwg_sentinel (DWG_SENTINEL_THUMBNAIL_BEGIN);
2274 if (memcmp (sentinel, sec_dat.chain, 16))
2275 {
2276 LOG_WARN ("thumbnail sentinel mismatch");
2277 return error |= DWG_ERR_WRONGCRC;
2278 }
2279
2280 assert (sec_dat.size >= 32);
2281 assert (sec_dat.chain);
2282 dwg->thumbnail.size = sec_dat.size - 32; // 2x sentinel
2283 dwg->thumbnail.chain = sec_dat.chain;
2284 dwg->thumbnail.byte = 16; // sentinel
2285
2286 dwg_bmp (dwg, &size);
2287 if (abs ((int)((long)size - (long)dwg->thumbnail.size))
2288 > 200) // various headers
2289 LOG_WARN ("thumbnail.size mismatch: %lu != " FORMAT_RL,
2290 dwg->thumbnail.size, size);
2291
2292 dat->byte += dwg->thumbnail.size;
2293
2294 return error;
2295 }
2296
2297 /* exported */
2298 void
read_r2007_init(Dwg_Data * restrict dwg)2299 read_r2007_init (Dwg_Data *restrict dwg)
2300 {
2301 if (dwg->opts)
2302 loglevel = dwg->opts & DWG_OPTS_LOGLEVEL;
2303 }
2304
2305 int
read_r2007_meta_data(Bit_Chain * dat,Bit_Chain * hdl_dat,Dwg_Data * restrict dwg)2306 read_r2007_meta_data (Bit_Chain *dat, Bit_Chain *hdl_dat,
2307 Dwg_Data *restrict dwg)
2308 {
2309 r2007_file_header file_header;
2310 r2007_page *restrict pages_map = NULL, *restrict page;
2311 r2007_section *restrict sections_map = NULL;
2312 int error;
2313 #ifdef USE_TRACING
2314 char *probe;
2315 #endif
2316
2317 read_r2007_init (dwg);
2318 #ifdef USE_TRACING
2319 probe = getenv ("LIBREDWG_TRACE");
2320 if (probe)
2321 loglevel = atoi (probe);
2322 #endif
2323 // @ 0x62
2324 error = read_file_header (dat, &file_header);
2325 if (error >= DWG_ERR_VALUEOUTOFBOUNDS)
2326 return error;
2327
2328 // Pages Map
2329 dat->byte += 0x28; // overread check data
2330 dat->byte += file_header.pages_map_offset;
2331 if ((unsigned long)file_header.pages_map_size_comp
2332 > dat->size - dat->byte)
2333 {
2334 LOG_ERROR ("%s Invalid pages_map_size_comp %lu > %lu bytes left",
2335 __FUNCTION__,
2336 (unsigned long)file_header.pages_map_size_comp,
2337 dat->size - dat->byte)
2338 error |= DWG_ERR_VALUEOUTOFBOUNDS;
2339 goto error;
2340 }
2341 pages_map = read_pages_map (dat, file_header.pages_map_size_comp,
2342 file_header.pages_map_size_uncomp,
2343 file_header.pages_map_correction);
2344 if (!pages_map)
2345 return DWG_ERR_PAGENOTFOUND; // Error already logged
2346
2347 // Sections Map
2348 page = get_page (pages_map, file_header.sections_map_id);
2349 if (!page)
2350 {
2351 LOG_ERROR ("Failed to find sections page map %d",
2352 (int)file_header.sections_map_id);
2353 error |= DWG_ERR_SECTIONNOTFOUND;
2354 goto error;
2355 }
2356 dat->byte = page->offset;
2357 if ((unsigned long)file_header.sections_map_size_comp
2358 > dat->size - dat->byte)
2359 {
2360 LOG_ERROR ("%s Invalid comp_data_size %lu > %lu bytes left",
2361 __FUNCTION__,
2362 (unsigned long)file_header.sections_map_size_comp,
2363 dat->size - dat->byte)
2364 error |= DWG_ERR_VALUEOUTOFBOUNDS;
2365 goto error;
2366 }
2367 sections_map = read_sections_map (dat, file_header.sections_map_size_comp,
2368 file_header.sections_map_size_uncomp,
2369 file_header.sections_map_correction);
2370 if (!sections_map)
2371 goto error;
2372
2373 error = read_2007_section_header (dat, hdl_dat, dwg, sections_map,
2374 pages_map);
2375 if (dwg->header.summaryinfo_address)
2376 error |= read_2007_section_summary (dat, dwg, sections_map, pages_map);
2377 error |= read_2007_section_classes (dat, dwg, sections_map, pages_map);
2378 error |= read_2007_section_handles (dat, hdl_dat, dwg, sections_map,
2379 pages_map);
2380 error |= read_2007_section_auxheader (dat, dwg, sections_map, pages_map);
2381 if (dwg->header.thumbnail_address)
2382 error |= read_2007_section_preview (dat, dwg, sections_map, pages_map);
2383 error |= read_2007_section_appinfo (dat, dwg, sections_map, pages_map);
2384 error |= read_2007_section_appinfohistory (dat, dwg, sections_map, pages_map);
2385 error |= read_2007_section_filedeplist (dat, dwg, sections_map, pages_map);
2386 error |= read_2007_section_security (dat, dwg, sections_map, pages_map);
2387 error |= read_2007_section_revhistory (dat, dwg, sections_map, pages_map);
2388 error |= read_2007_section_objfreespace (dat, dwg, sections_map, pages_map);
2389 error |= read_2007_section_template (dat, dwg, sections_map, pages_map);
2390 if (dwg->header.vbaproj_address)
2391 error |= read_2007_section_vbaproject (dat, dwg, sections_map, pages_map);
2392 //error |= read_2007_section_signature (dat, dwg, sections_map, pages_map);
2393 error |= read_2007_section_acds (dat, dwg, sections_map, pages_map);
2394 // read_2007_blocks (dat, hdl_dat, dwg, sections_map, pages_map);
2395
2396 error:
2397 pages_destroy (pages_map);
2398 if (sections_map)
2399 sections_destroy (sections_map);
2400
2401 return error;
2402 }
2403