Coder Social home page Coder Social logo

sandyre / libopencad Goto Github PK

View Code? Open in Web Editor NEW
191.0 21.0 61.0 6.5 MB

OpenSource library under X/MIT license to work with CAD files (DWG/DXF). Please use repository linked below, this one is abandoned.

Home Page: https://github.com/nextgis-borsch/lib_opencad

License: MIT License

C++ 73.97% C 1.17% CMake 23.47% Objective-C 1.38%
cad autocad c-plus-plus-11 mit-license abandoned

libopencad's Introduction

libopencad

Ubuntu 14.04 (gcc 4.8 + clang): Build Status

OpenSource library under X11/MIT license for everyday use. Under development, but some of basic functionality is already available. This project is being developed by Alexandr Borzykh (sandyre) under mentorship of Dmitry Baryshnikov (NextGIS).

Current project state:

DWG Read Write Features Missing
R13-14 - - - -
R15 + - Reading of layers.Basic geometry reading. Exporting header variables and classes. Linetypes, CRC calculation, by-block reading.
R17 - - - -

Getting started

First you need to download repository

git clone https://github.com/sandyre/libopencad

Static library way

Then, run cmake

cmake CMakeLists.txt

Build the project

make -j4

At this point, you will have a static library at lib/libopencadstatic.(your OS static library extension) All you have to do now - is to link library with your project, and include associated header files - opencad_api.h, cadgeometries.h and others.

Dynamic library way

Then, run cmake

cmake -DBUILD_SHARED_LIBS=ON CMakeLists.txt

Build the project

make -j4

At this point, you will have a dynamic library at lib/libopencad{library version}.(your OS dynamic library extension) All you have to do now - is to link library with your project, and include associated header files - opencad_api.h, cadgeometries.h and others.

Library sources inclusion way

All you have to do is to link the lib/ directory to your project file tree, that's actually it.

Usage example

As an example of library usage, there is a built-in app called cadinfo (builds by default with library, available in apps/ directory).

#include <iostream>
# include "lib/opencad_api.h"

// returns nullptr on fail. GetLastErrorCode() returns an error code.
CADFile *pCADFile = OpenCADFile( pszCADFilePath,
                                      CADFile::OpenOptions::READ_ALL );

const CADHeader& header = pCADFile->getHeader ();
header.print (); // prints CAD Header variables.
cout << endl;

const CADClasses& classes = pCADFile->getClasses ();
classes.print (); // prints custom CAD classes
cout << endl;

for ( size_t i = 0; i < pCADFile->getLayersCount (); ++i )
{
    CADLayer &layer = pCADFile->getLayer (i);
    cout << "Layer #" << i << " contains "
         << layer.getGeometryCount () << " geometries" << endl;

    for ( size_t j = 0; j < layer.getGeometryCount (); ++j )
    {
        unique_ptr<CADGeometry> geom(layer.getGeometry (j));

        if ( geom == nullptr )
            continue;

        switch ( geom->getType() ) // returns GeometryType enum.
        {
            case CADGeometry::CIRCLE:
                CADCircle * poCADCircle = ( CADCircle* ) geom.get();
                std::cout << poCADCircle->getPosition().getX() << std::endl;
                std::cout << poCADCircle->getPosition().getY() << std::endl;
                std::cout << poCADCircle->getPosition().getZ() << std::endl;
                break;
            // any other geometry type you need.
        }
    }
}

Contribution

Feel free to submit an issue, or make a pull request. To begin with, it's better to fix some FIXME/TODO's, to get more familiar with code base.

Library documentation

Documentation is generated by Doxygen, available at this link

libopencad's People

Contributors

amdmi3 avatar bishopgis avatar feragon avatar jamierobertson1 avatar lbartoletti avatar luzpaz avatar mush3d avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

libopencad's Issues

Doesn't compile on i386 when time_t is defined as int

time_t is not necessary a long. On some architecture (for my case FreeBSD i386), time_t is defined as an int (and long for amd64). So, for 32 bits, libopencad doesn't compile:

lib/cadheader.h:78:5: error: constructor cannot be redeclared CADVariant( time_t val );
    ^
lib/cadheader.h:72:5: note: previous declaration is here CADVariant( int val );

See types.h

Polyline inconsistencies

There are inconsistencies between different Polyline implementations, for instance Polyline2d seems only half implemented, (there's a CADPolyline2DObject, but no corresponding CADPolyline2D geometry class). Also the "isClosed" flag is only implemented for LW Polylines. I can submit a pull request if you like and just add a CADPolyline2D class which inherits from CADPolyline3D

Regards

Jamie

Heap-buffer-overflow in io.cpp:331 and io.cpp:444

Hi, I found some heap overflow when I compiled 'cadinfo' with ASan(use options -fsanitize=address),

==135828==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60600000d3dc at pc 0x4ebdbf bp 0x7ffe5f02d0c0 sp 0x7ffe5f02d0b8
READ of size 2 at 0x60600000d3dc thread T0
    #0 0x4ebdbe in ReadCHAR(char const*, unsigned long&) /home/xxxx/testapp/libopencad-master/lib/dwg/io.cpp:331
    #1 0x4ed98f in ReadHANDLE(char const*, unsigned long&) /home/xxxx/testapp/libopencad-master/lib/dwg/io.cpp:693
    #2 0x4d672f in DWGFileR2000::getXRecord(long, char const*, unsigned long&) /home/xxxx/testapp/libopencad-master/lib/dwg/r2000.cpp:3773
    #3 0x4c05de in DWGFileR2000::GetObject(long, bool) /home/xxxx/testapp/libopencad-master/lib/dwg/r2000.cpp:982
    #4 0x4d7d40 in DWGFileR2000::GetNOD() /home/xxxx/testapp/libopencad-master/lib/dwg/r2000.cpp:3879
    #5 0x472c6a in main /home/xxxx/testapp/libopencad-master/apps/cadinfo.cpp:129
    #6 0x7fe52e607f44 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21f44)
    #7 0x4724d8 (/home/xxxx/testapp/libopencad-master/cadinfo+0x4724d8)

0x60600000d3dd is located 0 bytes to the right of 61-byte region [0x60600000d3a0,0x60600000d3dd)
allocated by thread T0 here:
    #0 0x7fe52f23827f in operator new[](unsigned long) (/usr/lib/x86_64-linux-gnu/libasan.so.1+0x5527f)
    #1 0x4bf24f in DWGFileR2000::GetObject(long, bool) /home/xxxx/testapp/libopencad-master/lib/dwg/r2000.cpp:778
    #2 0x4d7d40 in DWGFileR2000::GetNOD() /home/xxxx/testapp/libopencad-master/lib/dwg/r2000.cpp:3879
    #3 0x472c6a in main /home/xxxx/testapp/libopencad-master/apps/cadinfo.cpp:129
    #4 0x7fe52e607f44 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21f44)

SUMMARY: AddressSanitizer: heap-buffer-overflow /home/xxxx/testapp/libopencad-master/lib/dwg/io.cpp:331 ReadCHAR(char const*, unsigned long&)
Shadow bytes around the buggy address:
  0x0c0c7fff9a20: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0c7fff9a30: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0c7fff9a40: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0c7fff9a50: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0c7fff9a60: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00
=>0x0c0c7fff9a70: fa fa fa fa 00 00 00 00 00 00 00[05]fa fa fa fa
  0x0c0c7fff9a80: fd fd fd fd fd fd fd fd fa fa fa fa 00 00 00 00
  0x0c0c7fff9a90: 00 00 00 01 fa fa fa fa 00 00 00 00 00 00 00 01
  0x0c0c7fff9aa0: fa fa fa fa 00 00 00 00 00 00 00 01 fa fa fa fa
  0x0c0c7fff9ab0: 00 00 00 00 00 00 00 01 fa fa fa fa 00 00 00 00
  0x0c0c7fff9ac0: 00 00 00 01 fa fa fa fa 00 00 00 00 00 00 00 01
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Heap right redzone:      fb
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack partial redzone:   f4
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Contiguous container OOB:fc
  ASan internal:           fe
==135828==ABORTING

And

==163526==ERROR: AddressSanitizer: unknown-crash on address 0x61700000fb9e at pc 0x4ec6d8 bp 0x7ffca1e30940 sp 0x7ffca1e30938
READ of size 8 at 0x61700000fb9e thread T0
    #0 0x4ec6d7 in ReadMCHAR(char const*, unsigned long&) /home/xxxx/testapp/libopencad-master/lib/dwg/io.cpp:444
    #1 0x4bedc9 in DWGFileR2000::CreateFileMap() /home/xxxx/testapp/libopencad-master/lib/dwg/r2000.cpp:737
    #2 0x476b89 in CADFile::ParseFile(CADFile::OpenOptions, bool) /home/xxxx/testapp/libopencad-master/lib/cadfile.cpp:86
    #3 0x47629c in OpenCADFile(CADFileIO*, CADFile::OpenOptions, bool) /home/xxxx/testapp/libopencad-master/lib/opencad.cpp:104
    #4 0x476490 in OpenCADFile(char const*, CADFile::OpenOptions, bool) /home/xxxx/testapp/libopencad-master/lib/opencad.cpp:190
    #5 0x472b14 in main /home/xxxx/testapp/libopencad-master/apps/cadinfo.cpp:111
    #6 0x7f6ce110cf44 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21f44)
    #7 0x4724d8 (/home/xxxx/testapp/libopencad-master/cadinfo+0x4724d8)

0x61700000fba5 is located 0 bytes to the right of 677-byte region [0x61700000f900,0x61700000fba5)
allocated by thread T0 here:
    #0 0x7f6ce1d3d27f in operator new[](unsigned long) (/usr/lib/x86_64-linux-gnu/libasan.so.1+0x5527f)
    #1 0x4becd3 in DWGFileR2000::CreateFileMap() /home/xxxx/testapp/libopencad-master/lib/dwg/r2000.cpp:727
    #2 0x476b89 in CADFile::ParseFile(CADFile::OpenOptions, bool) /home/xxxx/testapp/libopencad-master/lib/cadfile.cpp:86
    #3 0x47629c in OpenCADFile(CADFileIO*, CADFile::OpenOptions, bool) /home/xxxx/testapp/libopencad-master/lib/opencad.cpp:104
    #4 0x476490 in OpenCADFile(char const*, CADFile::OpenOptions, bool) /home/xxxxx/testapp/libopencad-master/lib/opencad.cpp:190
    #5 0x472b14 in main /home/xxxxx/testapp/libopencad-master/apps/cadinfo.cpp:111
    #6 0x7f6ce110cf44 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21f44)

SUMMARY: AddressSanitizer: unknown-crash /home/xxxx/testapp/libopencad-master/lib/dwg/io.cpp:444 ReadMCHAR(char const*, unsigned long&)
Shadow bytes around the buggy address:
  0x0c2e7fff9f20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c2e7fff9f30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c2e7fff9f40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c2e7fff9f50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c2e7fff9f60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c2e7fff9f70: 00 00 00[00]05 fa fa fa fa fa fa fa fa fa fa fa
  0x0c2e7fff9f80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c2e7fff9f90: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c2e7fff9fa0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c2e7fff9fb0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
  0x0c2e7fff9fc0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Heap right redzone:      fb
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack partial redzone:   f4
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Contiguous container OOB:fc
  ASan internal:           fe
==163526==ABORTING

POC file
poc1
poc2

by-block reading

As well as library reads Layers, that would be a perfect enhancement to add by-block reading (as an example - same API as CADLayer provides).

Null pointer dereference in DWGFileR2000::ReadHeader

crash context in gdb

pwndbg> r
Starting program: /home/xxx/workplace/asan/libopencad/build/apps/cadinfo null-ptr-opencad.dwg

Program received signal SIGSEGV, Segmentation fault.
0x000000000049f31c in DWGFileR2000::ReadHeader (this=0x6f6a90, eOptions=CADFile::READ_ALL) at /home/xxx/workplace/asan/libopencad/lib/dwg/r2000.cpp:71
71      pFileIO->Seek( sectionLocatorRecords[0].dSeeker, CADFileIO::SeekOrigin::BEG );
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
───────────────────────────────────────────────────────────────────────────────[ REGISTERS ]────────────────────────────────────────────────────────────────────────────────
 RAX  0x0
 RBX  0x478102 ◂— push   rbp
 RCX  0x0
 RDX  0x0
 RDI  0x6f6b68 ◂— 0x0
 RSI  0x0
 R8   0x7fffffffd9df ◂— 0x7fffffffda0000
 R9   0x9
 R10  0x7ffff75b1fe0 (_IO_strn_jumps) ◂— 0x0
 R11  0x1
 R12  0x4737a0 (_start) ◂— xor    ebp, ebp
 R13  0x7fffffffe100 ◂— 0x2
 R14  0x0
 R15  0x0
 RBP  0x7fffffffdc90 —▸ 0x7fffffffdcc0 —▸ 0x7fffffffdd00 —▸ 0x7fffffffdd30 —▸ 0x7fffffffe020 ◂— ...
 RSP  0x7fffffffcc20 ◂— 0x0
 RIP  0x49f31c (DWGFileR2000::ReadHeader(CADFile::OpenOptions)+98) ◂— mov    eax, dword ptr [rax + 4]
─────────────────────────────────────────────────────────────────────────────────[ DISASM ]─────────────────────────────────────────────────────────────────────────────────
 ► 0x49f31c <DWGFileR2000::ReadHeader(CADFile::OpenOptions)+98>     mov    eax, dword ptr [rax + 4]
   0x49f31f <DWGFileR2000::ReadHeader(CADFile::OpenOptions)+101>    movsxd rcx, eax
   0x49f322 <DWGFileR2000::ReadHeader(CADFile::OpenOptions)+104>    mov    rax, qword ptr [rbp - 0x1058]
   0x49f329 <DWGFileR2000::ReadHeader(CADFile::OpenOptions)+111>    mov    rax, qword ptr [rax + 8]
   0x49f32d <DWGFileR2000::ReadHeader(CADFile::OpenOptions)+115>    mov    edx, 0
   0x49f332 <DWGFileR2000::ReadHeader(CADFile::OpenOptions)+120>    mov    rsi, rcx
   0x49f335 <DWGFileR2000::ReadHeader(CADFile::OpenOptions)+123>    mov    rdi, rax
   0x49f338 <DWGFileR2000::ReadHeader(CADFile::OpenOptions)+126>    call   rbx
 
   0x49f33a <DWGFileR2000::ReadHeader(CADFile::OpenOptions)+128>    mov    rax, qword ptr [rbp - 0x1058]
   0x49f341 <DWGFileR2000::ReadHeader(CADFile::OpenOptions)+135>    mov    rax, qword ptr [rax + 8]
   0x49f345 <DWGFileR2000::ReadHeader(CADFile::OpenOptions)+139>    mov    rax, qword ptr [rax]
─────────────────────────────────────────────────────────────────────────────[ SOURCE (CODE) ]──────────────────────────────────────────────────────────────────────────────
In file: /home/xxx/workplace/asan/libopencad/lib/dwg/r2000.cpp
   66 {
   67     char buffer[255];
   68     char * pabyBuf;
   69     size_t dHeaderVarsSectionLength = 0;
   70 
 ► 71     pFileIO->Seek( sectionLocatorRecords[0].dSeeker, CADFileIO::SeekOrigin::BEG );
   72     pFileIO->Read( buffer, DWGSentinelLength );
   73     if( memcmp( buffer, DWGHeaderVariablesStart, DWGSentinelLength ) )
   74     {
   75         DebugMsg( "File is corrupted (wrong pointer to HEADER_VARS section,"
   76                           "or HEADERVARS starting sentinel corrupted.)" );
─────────────────────────────────────────────────────────────────────────────────[ STACK ]──────────────────────────────────────────────────────────────────────────────────
00:0000│ rsp  0x7fffffffcc20 ◂— 0x0
... ↓
03:0018│      0x7fffffffcc38 —▸ 0x6f6a90 —▸ 0x6f0d30 —▸ 0x4b5ff6 (DWGFileR2000::~DWGFileR2000()) ◂— push   rbp
04:0020│      0x7fffffffcc40 ◂— 0x0
... ↓
───────────────────────────────────────────────────────────────────────────────[ BACKTRACE ]────────────────────────────────────────────────────────────────────────────────
 ► f 0           49f31c DWGFileR2000::ReadHeader(CADFile::OpenOptions)+98
   f 1           4763b0
   f 2           475ead
   f 3           47604d
   f 4           473bf9 main+610
   f 5     7ffff7212f45 __libc_start_main+245
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Program received signal SIGSEGV (fault address 0x4)
pwndbg> 

poc

https://github.com/hac425xxx/fuzzdata/blob/master/null-ptr-opencad.dwg

About POLYLINE3D

I found that the geometry 3DPOLY in autocad can't be identified with libopencad. Doesn't it match to the CADGeometry POLYLINED?

stack-buffer-overflow in libopencad

AddressSanitizer Output

~/workplace/asan/libopencad/build$ ./apps/cadinfo stack-bof-opencad.dwg 
=================================================================
==165126== ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffc70845dab at pc 0x47b21c bp 0x7ffc70845d50 sp 0x7ffc70845d48
WRITE of size 1 at 0x7ffc70845dab thread T0
    #0 0x47b21b (/home/xxx/workplace/asan/libopencad/build/apps/cadinfo+0x47b21b)
    #1 0x47c36f (/home/xxx/workplace/asan/libopencad/build/apps/cadinfo+0x47c36f)
    #2 0x4bae59 (/home/xxx/workplace/asan/libopencad/build/apps/cadinfo+0x4bae59)
    #3 0x477c9e (/home/xxx/workplace/asan/libopencad/build/apps/cadinfo+0x477c9e)
    #4 0x47749c (/home/xxx/workplace/asan/libopencad/build/apps/cadinfo+0x47749c)
    #5 0x47768d (/home/xxx/workplace/asan/libopencad/build/apps/cadinfo+0x47768d)
    #6 0x47426c (/home/xxx/workplace/asan/libopencad/build/apps/cadinfo+0x47426c)
    #7 0x7fb1d298ff44 (/lib/x86_64-linux-gnu/libc-2.19.so+0x21f44)
    #8 0x473ca8 (/home/xxx/workplace/asan/libopencad/build/apps/cadinfo+0x473ca8)
Address 0x7ffc70845dab is located at offset 43 in frame <getAsLong> of T0's stack:
  This frame has 1 object(s):
    [32, 40) 'result'
HINT: this may be a false positive if your program uses some custom stack unwind mechanism or swapcontext
      (longjmp and C++ exceptions *are* supported)
Shadow bytes around the buggy address:
  0x10000e100b60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10000e100b70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10000e100b80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10000e100b90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10000e100ba0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x10000e100bb0: f1 f1 f1 f1 00[f4]f4 f4 f3 f3 f3 f3 00 00 00 00
  0x10000e100bc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10000e100bd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10000e100be0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10000e100bf0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10000e100c00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:     fa
  Heap righ redzone:     fb
  Freed Heap region:     fd
  Stack left redzone:    f1
  Stack mid redzone:     f2
  Stack right redzone:   f3
  Stack partial redzone: f4
  Stack after return:    f5
  Stack use after scope: f8
  Global redzone:        f9
  Global init order:     f6
  Poisoned by user:      f7
  ASan internal:         fe
==165126== ABORTING

poc

https://github.com/hac425xxx/fuzzdata/blob/master/stack-bof-opencad.dwg

heap buffer overflow in CADFile::ReadTables

crash context

pwndbg> r
Starting program: /home/xxx/workplace/asan/libopencad/build/cadinfo_debug heapoverflow-2-opencad.dwg

Program received signal SIGSEGV, Segmentation fault.
0x00000000004c2788 in Read2B (pabyInput=0x7035e0 "D5D\\\304\061\001Q\251DiDeD>\035*", nBitOffsetFromStart=@0x7fffffffc868: 9166815975) at /home/xxx/workplace/asan/libopencad/lib/dwg/io.cpp:58
58      memcpy( a2BBytes, p2BByte, 2 );
LEGEND: STACK | HEAP | CODE | DATA | RWX | RODATA
───────────────────────────────────────────────────────────────────────────────[ REGISTERS ]────────────────────────────────────────────────────────────────────────────────
 RAX  0x44bc863c
 RBX  0x478102 ◂— push   rbp
 RCX  0x1
 RDX  0x7035e0 ◂— 0x510131c45c443544
 RDI  0x7035e0 ◂— 0x510131c45c443544
 RSI  0x7fffffffc868 ◂— 0x2226282e7
 R8   0x703280 ◂— 0xe821b93232b637a4
 R9   0x0
 R10  0x7fffffffc560 —▸ 0x703080 ◂— 0x91d19e49120400a0
 R11  0x7ffff737c310 ◂— jle    0x7ffff737c2bc
 R12  0x4737a0 (_start) ◂— xor    ebp, ebp
 R13  0x7fffffffe100 ◂— 0x2
 R14  0x0
 R15  0x0
 RBP  0x7fffffffc820 —▸ 0x7fffffffdaa0 —▸ 0x7fffffffdc10 —▸ 0x7fffffffdc60 —▸ 0x7fffffffdc90 ◂— ...
 RSP  0x7fffffffc820 —▸ 0x7fffffffdaa0 —▸ 0x7fffffffdc10 —▸ 0x7fffffffdc60 —▸ 0x7fffffffdc90 ◂— ...
 RIP  0x4c2788 ◂— movzx  eax, word ptr [rax]
─────────────────────────────────────────────────────────────────────────────────[ DISASM ]─────────────────────────────────────────────────────────────────────────────────
 ► 0x4c2788    movzx  eax, word ptr [rax]
   0x4c278b    mov    word ptr [rbp - 0x20], ax
   0x4c278f    mov    rax, qword ptr [rbp - 0x10]
   0x4c2793    cmp    rax, 7
   0x4c2797    jne    0x4c27b1
    ↓
   0x4c27b1    movzx  eax, byte ptr [rbp - 0x20]
   0x4c27b5    movzx  edx, al
   0x4c27b8    mov    rax, qword ptr [rbp - 0x10]
   0x4c27bc    mov    ecx, 6
   0x4c27c1    sub    ecx, eax
   0x4c27c3    mov    eax, ecx
─────────────────────────────────────────────────────────────────────────────[ SOURCE (CODE) ]──────────────────────────────────────────────────────────────────────────────
In file: /home/xxx/workplace/asan/libopencad/lib/dwg/io.cpp
   53     size_t        nByteOffset      = nBitOffsetFromStart / 8;
   54     size_t        nBitOffsetInByte = nBitOffsetFromStart % 8;
   55 
   56     const char * p2BByte = pabyInput + nByteOffset;
   57     unsigned char a2BBytes[2];
 ► 58     memcpy( a2BBytes, p2BByte, 2 );
   59 
   60     switch( nBitOffsetInByte )
   61     {
   62         case 7:
   63             result = ( a2BBytes[0] & binary(00000001) ) << 1;
─────────────────────────────────────────────────────────────────────────────────[ STACK ]──────────────────────────────────────────────────────────────────────────────────
00:0000│ rbp rsp  0x7fffffffc820 —▸ 0x7fffffffdaa0 —▸ 0x7fffffffdc10 —▸ 0x7fffffffdc60 —▸ 0x7fffffffdc90 ◂— ...
01:0008│          0x7fffffffc828 —▸ 0x4a61dd ◂— mov    byte ptr [rbp - 0x1130], al
02:0010│          0x7fffffffc830 —▸ 0x7fffffffcacf ◂— 0xec0e332900
03:0018│          0x7fffffffc838 ◂— 0x7f00ffffc809
04:0020│          0x7fffffffc840 ◂— 0x1f
05:0028│          0x7fffffffc848 —▸ 0x6f6a90 —▸ 0x6f0d30 —▸ 0x4b5ff6 (DWGFileR2000::~DWGFileR2000()) ◂— push   rbp
06:0030│          0x7fffffffc850 ◂— 0x117fffffffcaf0
07:0038│          0x7fffffffc858 ◂— 0x354400000100
───────────────────────────────────────────────────────────────────────────────[ BACKTRACE ]────────────────────────────────────────────────────────────────────────────────
 ► f 0           4c2788
   f 1           4a61dd
   f 2           47e63c
   f 3           47e1b2
   f 4           476469 CADFile::ReadTables(CADFile::OpenOptions)+43
   f 5           476429
   f 6           475ead
   f 7           47604d
   f 8           473bf9 main+610
   f 9     7ffff7212f45 __libc_start_main+245
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Program received signal SIGSEGV (fault address 0x44bc863c)
pwndbg> 

program crash because p2BByte is inaccessible.

 const char * p2BByte = pabyInput + nByteOffset;
 unsigned char a2BBytes[2];
 memcpy( a2BBytes, p2BByte, 2 );

the pabyInput is a heap buffer which contain the content of our input dwg file and nByteOffset is too large.

pwndbg> p/x nByteOffset
$2 = 0x444c505c
pwndbg> 

This lead to heap buffer overflow

The poc

https://github.com/hac425xxx/fuzzdata/blob/master/heapoverflow-2-opencad.dwg

Which DWG versions are supported?

I noticed that some DWG files cannot be read since I get "open name_file.dwg failed". What are the suggested DWG versions that is better to use?
Thank you!

P.S. For example, I cannot read this DWG file.
sample.zip

DOS in libopencad

when parse a crafted dwg file , libopencad could dos and cpu 100%

cmdline

./cadinfo ddos_opencad.dwg

poc

https://github.com/hac425xxx/fuzzdata/blob/master/ddos_opencad.dwg

Failed to build library on Windows

Has anyone tried to build this library for Windows? When I'm trying to build this lib for Windows I see a lot of syntax errors (for about 1500).
So could you please advise here?
I use MS VS 2017.
Here are steps I'm following to build library:

  1. Run cmake CMakeLists.txt
  2. Launch libopencad.sln
  3. Build the solution in microsoft visual studio 2017

I attached screenshot with the problems.
image

When can this lib support AC1018?

Recently, I have try to transform the high dwg version to autocad2000, but it seems this lib has some bugs. Such as some layers' geometries losed or exists bugs when opencadfile().
Is it because the geometrytype is not enough for versions after transform. Can you continue to update the lib??Thank you.

heapoverflow in libopencad

AddressSanitizer output:

~/workplace/asan/libopencad/build$ ./apps/cadinfo ppp.dwg 
=================================================================
==85678== ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60040000d630 at pc 0x4ea8c8 bp 0x7ffde620cc50 sp 0x7ffde620cc48
READ of size 8 at 0x60040000d630 thread T0
    #0 0x4ea8c7 (/home/xxx/workplace/asan/libopencad/build/apps/cadinfo+0x4ea8c7)
    #1 0x4bda94 (/home/xxx/workplace/asan/libopencad/build/apps/cadinfo+0x4bda94)
    #2 0x477d75 (/home/xxx/workplace/asan/libopencad/build/apps/cadinfo+0x477d75)
    #3 0x47749c (/home/xxx/workplace/asan/libopencad/build/apps/cadinfo+0x47749c)
    #4 0x47768d (/home/xxx/workplace/asan/libopencad/build/apps/cadinfo+0x47768d)
    #5 0x47426c (/home/xxx/workplace/asan/libopencad/build/apps/cadinfo+0x47426c)
    #6 0x7fc872206f44 (/lib/x86_64-linux-gnu/libc-2.19.so+0x21f44)
    #7 0x473ca8 (/home/xxx/workplace/asan/libopencad/build/apps/cadinfo+0x473ca8)
0x60040000d634 is located 0 bytes to the right of 4-byte region [0x60040000d630,0x60040000d634)
allocated by thread T0 here:
    #0 0x7fc872ddf88a (/usr/lib/x86_64-linux-gnu/libasan.so.0.0.0+0x1188a)
    #1 0x4bd9bb (/home/xxx/workplace/asan/libopencad/build/apps/cadinfo+0x4bd9bb)
    #2 0x477d75 (/home/xxx/workplace/asan/libopencad/build/apps/cadinfo+0x477d75)
    #3 0x47749c (/home/xxx/workplace/asan/libopencad/build/apps/cadinfo+0x47749c)
    #4 0x47768d (/home/xxx/workplace/asan/libopencad/build/apps/cadinfo+0x47768d)
    #5 0x47426c (/home/xxx/workplace/asan/libopencad/build/apps/cadinfo+0x47426c)
    #6 0x7fc872206f44 (/lib/x86_64-linux-gnu/libc-2.19.so+0x21f44)
Shadow bytes around the buggy address:
  0x0c00ffff9a70: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c00ffff9a80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c00ffff9a90: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c00ffff9aa0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c00ffff9ab0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x0c00ffff9ac0: fa fa fa fa fa fa[04]fa fa fa fd fa fa fa fd fa
  0x0c00ffff9ad0: fa fa fd fa fa fa 01 fa fa fa fd fa fa fa fd fa
  0x0c00ffff9ae0: fa fa 01 fa fa fa fd fa fa fa fd fa fa fa 01 fa
  0x0c00ffff9af0: fa fa fd fa fa fa fd fa fa fa 01 fa fa fa fd fa
  0x0c00ffff9b00: fa fa fd fa fa fa 01 fa fa fa fd fa fa fa fd fa
  0x0c00ffff9b10: fa fa 01 fa fa fa fd fa fa fa fd fa fa fa 01 fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:     fa
  Heap righ redzone:     fb
  Freed Heap region:     fd
  Stack left redzone:    f1
  Stack mid redzone:     f2
  Stack right redzone:   f3
  Stack partial redzone: f4
  Stack after return:    f5
  Stack use after scope: f8
  Global redzone:        f9
  Global init order:     f6
  Poisoned by user:      f7
  ASan internal:         fe
==85678== ABORTING

poc

https://github.com/hac425xxx/fuzzdata/blob/master/heapoverflow-opencad.dwg

CRC calculation

Need to implement CRC calculation for existing DWG versions (R2000 only for the time opening the issue), and calculate it in every section/object/block if READ_ALL param was passed.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.