diff --git a/src/drw_base.h b/src/drw_base.h index d57d7a1..95cbc7f 100644 --- a/src/drw_base.h +++ b/src/drw_base.h @@ -108,6 +108,19 @@ enum DBG_LEVEL { DEBUG }; +/** + * Exception raised when memory allocation fails. + */ +class MemoryAllocationException { +public: + MemoryAllocationException(std::string what) + : mWhat{what} + {} + std::string message() const throw() {return mWhat;} + private: + std::string mWhat; +}; + //! Special codes for colors enum ColorCodes { ColorByLayer = 256, diff --git a/src/drw_entities.cpp b/src/drw_entities.cpp index 05469ad..d8cc389 100644 --- a/src/drw_entities.cpp +++ b/src/drw_entities.cpp @@ -12,10 +12,21 @@ #include #include "drw_entities.h" +#include "drw_base.h" #include "intern/dxfreader.h" #include "intern/dwgbuffer.h" #include "intern/drw_dbg.h" +#define RESERVE(vector,size,msg) try { \ + vector.reserve(size); \ + } catch(const std::exception &e) { \ + std::stringstream s; \ + s << msg << " size=" << size << "; error="; \ + s << e.what(); \ + throw DRW::MemoryAllocationException(s.str()); \ + } + + //! Calculate arbitrary axis /*! * Calculate arbitrary axis for apply extrusions @@ -1165,7 +1176,7 @@ void DRW_LWPolyline::parseCode(int code, dxfReader *reader){ break; case 90: vertexnum = reader->getInt32(); - vertlist.reserve(vertexnum); + RESERVE(vertlist,vertexnum,"vertex list") break; case 210: haveExtrusion = true; @@ -1200,7 +1211,7 @@ bool DRW_LWPolyline::parseDwg(DRW::Version version, dwgBuffer *buf, duint32 bs){ if (flags & 1) extPoint = buf->getExtrusion(false); vertexnum = buf->getBitLong(); - vertlist.reserve(vertexnum); + RESERVE(vertlist,vertexnum,"vertex list") unsigned int bulgesnum = 0; if (flags & 16) bulgesnum = buf->getBitLong(); @@ -1791,7 +1802,7 @@ void DRW_Hatch::parseCode(int code, dxfReader *reader){ break; case 91: loopsnum = reader->getInt32(); - looplist.reserve(loopsnum); + RESERVE(looplist,loopsnum,"loop list") break; case 92: loop = std::make_shared(reader->getInt32()); @@ -1903,12 +1914,12 @@ bool DRW_Hatch::parseDwg(DRW::Version version, dwgBuffer *buf, duint32 bs){ spline->flags |= (isRational << 2); //rational spline->flags |= (buf->getBit() << 1); //periodic spline->nknots = buf->getBitLong(); - spline->knotslist.reserve(spline->nknots); + RESERVE(spline->knotslist,spline->nknots,"knots list") for (dint32 j = 0; j < spline->nknots;++j){ spline->knotslist.push_back (buf->getBitDouble()); } spline->ncontrol = buf->getBitLong(); - spline->controllist.reserve(spline->ncontrol); + RESERVE(spline->controllist,spline->ncontrol,"control list") for (dint32 j = 0; j < spline->ncontrol;++j){ std::shared_ptr crd = std::make_shared(buf->get3BitDouble()); spline->controllist.push_back(crd); @@ -1918,7 +1929,7 @@ bool DRW_Hatch::parseDwg(DRW::Version version, dwgBuffer *buf, duint32 bs){ } if (version > DRW::AC1021) { //2010+ spline->nfit = buf->getBitLong(); - spline->fitlist.reserve(spline->nfit); + RESERVE(spline->fitlist,spline->nfit,"fit list") for (dint32 j = 0; j < spline->nfit;++j){ std::shared_ptr crd = std::make_shared(buf->get3BitDouble()); spline->fitlist.push_back(crd); @@ -2142,17 +2153,17 @@ bool DRW_Spline::parseDwg(DRW::Version version, dwgBuffer *buf, duint32 bs){ return false; //RLZ: from doc only 1 or 2 are ok ? } - knotslist.reserve(nknots); + RESERVE(knotslist,nknots,"knots list") for (dint32 i= 0; igetBitDouble()); } - controllist.reserve(ncontrol); + RESERVE(controllist,ncontrol,"control list") for (dint32 i= 0; i(buf->get3BitDouble())); if (weight) DRW_DBG("\n w: "); DRW_DBG(buf->getBitDouble()); //RLZ Warning: D (BD or RD) } - fitlist.reserve(nfit); + RESERVE(fitlist,nfit,"fit list") for (dint32 i= 0; i(buf->get3BitDouble())); diff --git a/src/drw_objects.cpp b/src/drw_objects.cpp index 706ff58..3f93472 100644 --- a/src/drw_objects.cpp +++ b/src/drw_objects.cpp @@ -19,6 +19,15 @@ #include "intern/drw_dbg.h" #include "intern/dwgutil.h" +#define RESERVE(vector,size,msg) try { \ + vector.reserve(size); \ + } catch(const std::exception &e) { \ + std::stringstream s; \ + s << msg << " size=" << size << "; error="; \ + s << e.what(); \ + throw DRW::MemoryAllocationException(s.str()); \ + } + //! Base class for tables entries /*! * Base class for tables entries @@ -429,7 +438,7 @@ void DRW_LType::parseCode(int code, dxfReader *reader){ case 73: size = reader->getInt32(); path.clear(); - path.reserve(size); + RESERVE(path,size,"path") break; case 40: length = reader->getDouble(); @@ -703,7 +712,7 @@ bool DRW_Block_Record::parseDwg(DRW::Version version, dwgBuffer *buf, duint32 bs DRW_DBG("flags: "); DRW_DBG(flags); DRW_DBG(", "); if (version > DRW::AC1015) {//2004+ fails in 2007 objectCount = buf->getBitLong(); //Number of objects owned by this block - entMap.reserve(objectCount); + RESERVE(entMap,objectCount,"entity map") } basePoint.x = buf->getBitDouble(); basePoint.y = buf->getBitDouble();