Kaydet (Commit) f7bd3531 authored tarafından Stephan Bergmann's avatar Stephan Bergmann

cid#1213388 etc.: Make reflread.cxx more robust

incl. revert of and proper fix for 8f69c7a1
"coverity#1213373 Use of untrusted scalar value," the data is tainted after all

Change-Id: I19e4d544ccf6d02afe8d6e441cae6bbdadb8a6be
üst a7d798e3
...@@ -17,7 +17,9 @@ ...@@ -17,7 +17,9 @@
* the License at http://www.apache.org/licenses/LICENSE-2.0 . * the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/ */
#include <sal/config.h>
#include <cstring>
#include <memory> #include <memory>
#include <new> #include <new>
...@@ -52,6 +54,8 @@ const sal_uInt16 majorVersion = 0x0001; ...@@ -52,6 +54,8 @@ const sal_uInt16 majorVersion = 0x0001;
class BlopObject class BlopObject
{ {
public: public:
struct BoundsError {};
const sal_uInt8* m_pBuffer; const sal_uInt8* m_pBuffer;
sal_uInt32 m_bufferLen; sal_uInt32 m_bufferLen;
bool m_isCopied; bool m_isCopied;
...@@ -63,27 +67,33 @@ public: ...@@ -63,27 +67,33 @@ public:
inline sal_uInt8 readBYTE(sal_uInt32 index) const inline sal_uInt8 readBYTE(sal_uInt32 index) const
{ {
if (index >= m_bufferLen) {
throw BoundsError();
}
return m_pBuffer[index]; return m_pBuffer[index];
} }
inline sal_Int16 readINT16(sal_uInt32 index) const inline sal_Int16 readINT16(sal_uInt32 index) const
{ {
if (m_bufferLen < 2 || index >= m_bufferLen - 1) {
throw BoundsError();
}
return ((m_pBuffer[index] << 8) | (m_pBuffer[index+1] << 0)); return ((m_pBuffer[index] << 8) | (m_pBuffer[index+1] << 0));
} }
inline sal_uInt16 readUINT16(sal_uInt32 index) const inline sal_uInt16 readUINT16(sal_uInt32 index) const
{ {
//This is untainted data which comes from a controlled source if (m_bufferLen < 2 || index >= m_bufferLen - 1) {
//so, using a byte-swapping pattern which coverity doesn't throw BoundsError();
//detect as such }
//http://security.coverity.com/blog/2014/Apr/on-detecting-heartbleed-with-static-analysis.html return ((m_pBuffer[index] << 8) | (m_pBuffer[index+1] << 0));
sal_uInt32 v = m_pBuffer[index]; v <<= 8;
v |= m_pBuffer[index+1];
return v;
} }
inline sal_Int32 readINT32(sal_uInt32 index) const inline sal_Int32 readINT32(sal_uInt32 index) const
{ {
if (m_bufferLen < 4 || index >= m_bufferLen - 3) {
throw BoundsError();
}
return ( return (
(m_pBuffer[index] << 24) | (m_pBuffer[index] << 24) |
(m_pBuffer[index+1] << 16) | (m_pBuffer[index+1] << 16) |
...@@ -94,19 +104,22 @@ public: ...@@ -94,19 +104,22 @@ public:
inline sal_uInt32 readUINT32(sal_uInt32 index) const inline sal_uInt32 readUINT32(sal_uInt32 index) const
{ {
//This is untainted data which comes from a controlled source if (m_bufferLen < 4 || index >= m_bufferLen - 3) {
//so, using a byte-swapping pattern which coverity doesn't throw BoundsError();
//detect as such }
//http://security.coverity.com/blog/2014/Apr/on-detecting-heartbleed-with-static-analysis.html return (
sal_uInt32 v = m_pBuffer[index]; v <<= 8; (m_pBuffer[index] << 24) |
v |= m_pBuffer[index+1]; v <<= 8; (m_pBuffer[index+1] << 16) |
v |= m_pBuffer[index+2]; v <<= 8; (m_pBuffer[index+2] << 8) |
v |= m_pBuffer[index+3]; (m_pBuffer[index+3] << 0)
return v; );
} }
inline sal_Int64 readINT64(sal_uInt32 index) const inline sal_Int64 readINT64(sal_uInt32 index) const
{ {
if (m_bufferLen < 8 || index >= m_bufferLen - 7) {
throw BoundsError();
}
return ( return (
((sal_Int64)m_pBuffer[index] << 56) | ((sal_Int64)m_pBuffer[index] << 56) |
((sal_Int64)m_pBuffer[index+1] << 48) | ((sal_Int64)m_pBuffer[index+1] << 48) |
...@@ -121,6 +134,9 @@ public: ...@@ -121,6 +134,9 @@ public:
inline sal_uInt64 readUINT64(sal_uInt32 index) const inline sal_uInt64 readUINT64(sal_uInt32 index) const
{ {
if (m_bufferLen < 8 || index >= m_bufferLen - 7) {
throw BoundsError();
}
return ( return (
((sal_uInt64)m_pBuffer[index] << 56) | ((sal_uInt64)m_pBuffer[index] << 56) |
((sal_uInt64)m_pBuffer[index+1] << 48) | ((sal_uInt64)m_pBuffer[index+1] << 48) |
...@@ -244,8 +260,8 @@ public: ...@@ -244,8 +260,8 @@ public:
StringCache* m_pStringCache; StringCache* m_pStringCache;
ConstantPool(const sal_uInt8* buffer, sal_uInt16 numEntries) ConstantPool(const sal_uInt8* buffer, sal_uInt32 len, sal_uInt16 numEntries)
: BlopObject(buffer, 0, false) : BlopObject(buffer, len, false)
, m_numOfEntries(numEntries) , m_numOfEntries(numEntries)
, m_pIndex(NULL) , m_pIndex(NULL)
, m_pStringCache(NULL) , m_pStringCache(NULL)
...@@ -346,7 +362,11 @@ const sal_Char* ConstantPool::readUTF8NameConstant(sal_uInt16 index) ...@@ -346,7 +362,11 @@ const sal_Char* ConstantPool::readUTF8NameConstant(sal_uInt16 index)
{ {
if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_UTF8_NAME) if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_UTF8_NAME)
{ {
aName = (const sal_Char*) (m_pBuffer + m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA); sal_uInt32 n = m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA;
if (n < m_bufferLen && std::memchr(m_pBuffer, 0, n) != nullptr)
{
aName = (const sal_Char*) (m_pBuffer + n);
}
} }
} }
...@@ -543,7 +563,12 @@ const sal_Unicode* ConstantPool::readStringConstant(sal_uInt16 index) ...@@ -543,7 +563,12 @@ const sal_Unicode* ConstantPool::readStringConstant(sal_uInt16 index)
if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_CONST_STRING) if (readUINT16(m_pIndex[index - 1] + CP_OFFSET_ENTRY_TAG) == CP_TAG_CONST_STRING)
{ {
m_pIndex[index - 1] = -1 * m_pStringCache->createString(m_pBuffer + m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA); sal_uInt32 n = m_pIndex[index - 1] + CP_OFFSET_ENTRY_DATA;
if (n >= m_bufferLen || std::memchr(m_pBuffer, 0, n) == nullptr)
{
throw BoundsError();
}
m_pIndex[index - 1] = -1 * m_pStringCache->createString(m_pBuffer + n);
} }
} }
...@@ -591,8 +616,8 @@ public: ...@@ -591,8 +616,8 @@ public:
size_t m_FIELD_ENTRY_SIZE; size_t m_FIELD_ENTRY_SIZE;
ConstantPool* m_pCP; ConstantPool* m_pCP;
FieldList(const sal_uInt8* buffer, sal_uInt16 numEntries, ConstantPool* pCP) FieldList(const sal_uInt8* buffer, sal_uInt32 len, sal_uInt16 numEntries, ConstantPool* pCP)
: BlopObject(buffer, 0, false) : BlopObject(buffer, len, false)
, m_numOfEntries(numEntries) , m_numOfEntries(numEntries)
, m_pCP(pCP) , m_pCP(pCP)
{ {
...@@ -625,7 +650,11 @@ const sal_Char* FieldList::getFieldName(sal_uInt16 index) ...@@ -625,7 +650,11 @@ const sal_Char* FieldList::getFieldName(sal_uInt16 index)
if ((m_numOfEntries > 0) && (index <= m_numOfEntries)) if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
{ {
aName = m_pCP->readUTF8NameConstant(readUINT16(sizeof(sal_uInt16) + (index * m_FIELD_ENTRY_SIZE) + FIELD_OFFSET_NAME)); try {
aName = m_pCP->readUTF8NameConstant(readUINT16(sizeof(sal_uInt16) + (index * m_FIELD_ENTRY_SIZE) + FIELD_OFFSET_NAME));
} catch (BlopObject::BoundsError &) {
SAL_WARN("registry", "bad data");
}
} }
return aName; return aName;
...@@ -637,7 +666,11 @@ const sal_Char* FieldList::getFieldType(sal_uInt16 index) ...@@ -637,7 +666,11 @@ const sal_Char* FieldList::getFieldType(sal_uInt16 index)
if ((m_numOfEntries > 0) && (index <= m_numOfEntries)) if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
{ {
aName = m_pCP->readUTF8NameConstant(readUINT16(sizeof(sal_uInt16) + (index * m_FIELD_ENTRY_SIZE) + FIELD_OFFSET_TYPE)); try {
aName = m_pCP->readUTF8NameConstant(readUINT16(sizeof(sal_uInt16) + (index * m_FIELD_ENTRY_SIZE) + FIELD_OFFSET_TYPE));
} catch (BlopObject::BoundsError &) {
SAL_WARN("registry", "bad data");
}
} }
return aName; return aName;
...@@ -649,7 +682,11 @@ RTFieldAccess FieldList::getFieldAccess(sal_uInt16 index) ...@@ -649,7 +682,11 @@ RTFieldAccess FieldList::getFieldAccess(sal_uInt16 index)
if ((m_numOfEntries > 0) && (index <= m_numOfEntries)) if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
{ {
aAccess = (RTFieldAccess) readUINT16(sizeof(sal_uInt16) + (index * m_FIELD_ENTRY_SIZE) + FIELD_OFFSET_ACCESS); try {
aAccess = (RTFieldAccess) readUINT16(sizeof(sal_uInt16) + (index * m_FIELD_ENTRY_SIZE) + FIELD_OFFSET_ACCESS);
} catch (BlopObject::BoundsError &) {
SAL_WARN("registry", "bad data");
}
} }
return aAccess; return aAccess;
...@@ -658,13 +695,12 @@ RTFieldAccess FieldList::getFieldAccess(sal_uInt16 index) ...@@ -658,13 +695,12 @@ RTFieldAccess FieldList::getFieldAccess(sal_uInt16 index)
RTValueType FieldList::getFieldConstValue(sal_uInt16 index, RTConstValueUnion* value) RTValueType FieldList::getFieldConstValue(sal_uInt16 index, RTConstValueUnion* value)
{ {
RTValueType ret = RT_TYPE_NONE; RTValueType ret = RT_TYPE_NONE;
try {
if ((m_numOfEntries > 0) && (index <= m_numOfEntries)) if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
{
sal_uInt16 cpIndex = readUINT16(sizeof(sal_uInt16) + (index * m_FIELD_ENTRY_SIZE) + FIELD_OFFSET_VALUE);
switch (m_pCP->readTag(cpIndex))
{ {
sal_uInt16 cpIndex = readUINT16(sizeof(sal_uInt16) + (index * m_FIELD_ENTRY_SIZE) + FIELD_OFFSET_VALUE);
switch (m_pCP->readTag(cpIndex))
{
case CP_TAG_CONST_BOOL: case CP_TAG_CONST_BOOL:
value->aBool = m_pCP->readBOOLConstant(cpIndex); value->aBool = m_pCP->readBOOLConstant(cpIndex);
ret = RT_TYPE_BOOL; ret = RT_TYPE_BOOL;
...@@ -711,9 +747,11 @@ RTValueType FieldList::getFieldConstValue(sal_uInt16 index, RTConstValueUnion* v ...@@ -711,9 +747,11 @@ RTValueType FieldList::getFieldConstValue(sal_uInt16 index, RTConstValueUnion* v
break; break;
default: default:
break; break;
}
} }
} catch (BlopObject::BoundsError &) {
SAL_WARN("registry", "bad data");
} }
return ret; return ret;
} }
...@@ -723,7 +761,11 @@ const sal_Char* FieldList::getFieldDoku(sal_uInt16 index) ...@@ -723,7 +761,11 @@ const sal_Char* FieldList::getFieldDoku(sal_uInt16 index)
if ((m_numOfEntries > 0) && (index <= m_numOfEntries)) if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
{ {
aDoku = m_pCP->readUTF8NameConstant(readUINT16(sizeof(sal_uInt16) + (index * m_FIELD_ENTRY_SIZE) + FIELD_OFFSET_DOKU)); try {
aDoku = m_pCP->readUTF8NameConstant(readUINT16(sizeof(sal_uInt16) + (index * m_FIELD_ENTRY_SIZE) + FIELD_OFFSET_DOKU));
} catch (BlopObject::BoundsError &) {
SAL_WARN("registry", "bad data");
}
} }
return aDoku; return aDoku;
...@@ -735,7 +777,11 @@ const sal_Char* FieldList::getFieldFileName(sal_uInt16 index) ...@@ -735,7 +777,11 @@ const sal_Char* FieldList::getFieldFileName(sal_uInt16 index)
if ((m_numOfEntries > 0) && (index <= m_numOfEntries)) if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
{ {
aFileName = m_pCP->readUTF8NameConstant(readUINT16(sizeof(sal_uInt16) + (index * m_FIELD_ENTRY_SIZE) + FIELD_OFFSET_FILENAME)); try {
aFileName = m_pCP->readUTF8NameConstant(readUINT16(sizeof(sal_uInt16) + (index * m_FIELD_ENTRY_SIZE) + FIELD_OFFSET_FILENAME));
} catch (BlopObject::BoundsError &) {
SAL_WARN("registry", "bad data");
}
} }
return aFileName; return aFileName;
...@@ -756,8 +802,8 @@ public: ...@@ -756,8 +802,8 @@ public:
size_t m_REFERENCE_ENTRY_SIZE; size_t m_REFERENCE_ENTRY_SIZE;
ConstantPool* m_pCP; ConstantPool* m_pCP;
ReferenceList(const sal_uInt8* buffer, sal_uInt16 numEntries, ConstantPool* pCP) ReferenceList(const sal_uInt8* buffer, sal_uInt32 len, sal_uInt16 numEntries, ConstantPool* pCP)
: BlopObject(buffer, 0, false) : BlopObject(buffer, len, false)
, m_numOfEntries(numEntries) , m_numOfEntries(numEntries)
, m_pCP(pCP) , m_pCP(pCP)
{ {
...@@ -787,7 +833,11 @@ const sal_Char* ReferenceList::getReferenceName(sal_uInt16 index) ...@@ -787,7 +833,11 @@ const sal_Char* ReferenceList::getReferenceName(sal_uInt16 index)
if ((m_numOfEntries > 0) && (index <= m_numOfEntries)) if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
{ {
aName = m_pCP->readUTF8NameConstant(readUINT16(sizeof(sal_uInt16) + (index * m_REFERENCE_ENTRY_SIZE) + REFERENCE_OFFSET_NAME)); try {
aName = m_pCP->readUTF8NameConstant(readUINT16(sizeof(sal_uInt16) + (index * m_REFERENCE_ENTRY_SIZE) + REFERENCE_OFFSET_NAME));
} catch (BlopObject::BoundsError &) {
SAL_WARN("registry", "bad data");
}
} }
return aName; return aName;
...@@ -799,7 +849,11 @@ RTReferenceType ReferenceList::getReferenceType(sal_uInt16 index) ...@@ -799,7 +849,11 @@ RTReferenceType ReferenceList::getReferenceType(sal_uInt16 index)
if ((m_numOfEntries > 0) && (index <= m_numOfEntries)) if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
{ {
refType = (RTReferenceType) readUINT16(sizeof(sal_uInt16) + (index * m_REFERENCE_ENTRY_SIZE) + REFERENCE_OFFSET_TYPE); try {
refType = (RTReferenceType) readUINT16(sizeof(sal_uInt16) + (index * m_REFERENCE_ENTRY_SIZE) + REFERENCE_OFFSET_TYPE);
} catch (BlopObject::BoundsError &) {
SAL_WARN("registry", "bad data");
}
} }
return refType; return refType;
...@@ -811,7 +865,11 @@ const sal_Char* ReferenceList::getReferenceDoku(sal_uInt16 index) ...@@ -811,7 +865,11 @@ const sal_Char* ReferenceList::getReferenceDoku(sal_uInt16 index)
if ((m_numOfEntries > 0) && (index <= m_numOfEntries)) if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
{ {
aDoku = m_pCP->readUTF8NameConstant(readUINT16(sizeof(sal_uInt16) + (index * m_REFERENCE_ENTRY_SIZE) + REFERENCE_OFFSET_DOKU)); try {
aDoku = m_pCP->readUTF8NameConstant(readUINT16(sizeof(sal_uInt16) + (index * m_REFERENCE_ENTRY_SIZE) + REFERENCE_OFFSET_DOKU));
} catch (BlopObject::BoundsError &) {
SAL_WARN("registry", "bad data");
}
} }
return aDoku; return aDoku;
...@@ -823,7 +881,11 @@ RTFieldAccess ReferenceList::getReferenceAccess(sal_uInt16 index) ...@@ -823,7 +881,11 @@ RTFieldAccess ReferenceList::getReferenceAccess(sal_uInt16 index)
if ((m_numOfEntries > 0) && (index <= m_numOfEntries)) if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
{ {
aAccess = (RTFieldAccess) readUINT16(sizeof(sal_uInt16) + (index * m_REFERENCE_ENTRY_SIZE) + REFERENCE_OFFSET_ACCESS); try {
aAccess = (RTFieldAccess) readUINT16(sizeof(sal_uInt16) + (index * m_REFERENCE_ENTRY_SIZE) + REFERENCE_OFFSET_ACCESS);
} catch (BlopObject::BoundsError &) {
SAL_WARN("registry", "bad data");
}
} }
return aAccess; return aAccess;
...@@ -846,8 +908,8 @@ public: ...@@ -846,8 +908,8 @@ public:
sal_uInt32* m_pIndex; sal_uInt32* m_pIndex;
ConstantPool* m_pCP; ConstantPool* m_pCP;
MethodList(const sal_uInt8* buffer, sal_uInt16 numEntries, ConstantPool* pCP) MethodList(const sal_uInt8* buffer, sal_uInt32 len, sal_uInt16 numEntries, ConstantPool* pCP)
: BlopObject(buffer, 0, false) : BlopObject(buffer, len, false)
, m_numOfEntries(numEntries) , m_numOfEntries(numEntries)
, m_pIndex(NULL) , m_pIndex(NULL)
, m_pCP(pCP) , m_pCP(pCP)
...@@ -926,7 +988,11 @@ const sal_Char* MethodList::getMethodName(sal_uInt16 index) ...@@ -926,7 +988,11 @@ const sal_Char* MethodList::getMethodName(sal_uInt16 index)
if ((m_numOfEntries > 0) && (index <= m_numOfEntries)) if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
{ {
aName = m_pCP->readUTF8NameConstant(readUINT16(m_pIndex[index] + METHOD_OFFSET_NAME)); try {
aName = m_pCP->readUTF8NameConstant(readUINT16(m_pIndex[index] + METHOD_OFFSET_NAME));
} catch (BlopObject::BoundsError &) {
SAL_WARN("registry", "bad data");
}
} }
return aName; return aName;
...@@ -938,7 +1004,11 @@ sal_uInt16 MethodList::getMethodParamCount(sal_uInt16 index) ...@@ -938,7 +1004,11 @@ sal_uInt16 MethodList::getMethodParamCount(sal_uInt16 index)
if ((m_numOfEntries > 0) && (index <= m_numOfEntries)) if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
{ {
aCount = readUINT16(m_pIndex[index] + METHOD_OFFSET_PARAM_COUNT); try {
aCount = readUINT16(m_pIndex[index] + METHOD_OFFSET_PARAM_COUNT);
} catch (BlopObject::BoundsError &) {
SAL_WARN("registry", "bad data");
}
} }
return aCount; return aCount;
...@@ -947,53 +1017,59 @@ sal_uInt16 MethodList::getMethodParamCount(sal_uInt16 index) ...@@ -947,53 +1017,59 @@ sal_uInt16 MethodList::getMethodParamCount(sal_uInt16 index)
const sal_Char* MethodList::getMethodParamType(sal_uInt16 index, sal_uInt16 paramIndex) const sal_Char* MethodList::getMethodParamType(sal_uInt16 index, sal_uInt16 paramIndex)
{ {
const sal_Char* aName = NULL; const sal_Char* aName = NULL;
try {
if ((m_numOfEntries > 0) && if ((m_numOfEntries > 0) &&
(index <= m_numOfEntries) && (index <= m_numOfEntries) &&
(paramIndex <= readUINT16(m_pIndex[index] + METHOD_OFFSET_PARAM_COUNT))) (paramIndex <= readUINT16(m_pIndex[index] + METHOD_OFFSET_PARAM_COUNT)))
{ {
aName = m_pCP->readUTF8NameConstant( aName = m_pCP->readUTF8NameConstant(
readUINT16( readUINT16(
m_pIndex[index] + m_pIndex[index] +
calcMethodParamIndex(paramIndex) + calcMethodParamIndex(paramIndex) +
PARAM_OFFSET_TYPE)); PARAM_OFFSET_TYPE));
}
} catch (BlopObject::BoundsError &) {
SAL_WARN("registry", "bad data");
} }
return aName; return aName;
} }
const sal_Char* MethodList::getMethodParamName(sal_uInt16 index, sal_uInt16 paramIndex) const sal_Char* MethodList::getMethodParamName(sal_uInt16 index, sal_uInt16 paramIndex)
{ {
const sal_Char* aName = NULL; const sal_Char* aName = NULL;
try {
if ((m_numOfEntries > 0) && if ((m_numOfEntries > 0) &&
(index <= m_numOfEntries) && (index <= m_numOfEntries) &&
(paramIndex <= readUINT16(m_pIndex[index] + METHOD_OFFSET_PARAM_COUNT))) (paramIndex <= readUINT16(m_pIndex[index] + METHOD_OFFSET_PARAM_COUNT)))
{ {
aName = m_pCP->readUTF8NameConstant( aName = m_pCP->readUTF8NameConstant(
readUINT16( readUINT16(
m_pIndex[index] + m_pIndex[index] +
calcMethodParamIndex(paramIndex) + calcMethodParamIndex(paramIndex) +
PARAM_OFFSET_NAME)); PARAM_OFFSET_NAME));
}
} catch (BlopObject::BoundsError &) {
SAL_WARN("registry", "bad data");
} }
return aName; return aName;
} }
RTParamMode MethodList::getMethodParamMode(sal_uInt16 index, sal_uInt16 paramIndex) RTParamMode MethodList::getMethodParamMode(sal_uInt16 index, sal_uInt16 paramIndex)
{ {
RTParamMode aMode = RT_PARAM_INVALID; RTParamMode aMode = RT_PARAM_INVALID;
try {
if ((m_numOfEntries > 0) && if ((m_numOfEntries > 0) &&
(index <= m_numOfEntries) && (index <= m_numOfEntries) &&
(paramIndex <= readUINT16(m_pIndex[index] + METHOD_OFFSET_PARAM_COUNT))) (paramIndex <= readUINT16(m_pIndex[index] + METHOD_OFFSET_PARAM_COUNT)))
{ {
aMode = (RTParamMode) readUINT16( aMode = (RTParamMode) readUINT16(
m_pIndex[index] + m_pIndex[index] +
calcMethodParamIndex(paramIndex) + calcMethodParamIndex(paramIndex) +
PARAM_OFFSET_MODE); PARAM_OFFSET_MODE);
}
} catch (BlopObject::BoundsError &) {
SAL_WARN("registry", "bad data");
} }
return aMode; return aMode;
} }
...@@ -1003,7 +1079,11 @@ sal_uInt16 MethodList::getMethodExcCount(sal_uInt16 index) ...@@ -1003,7 +1079,11 @@ sal_uInt16 MethodList::getMethodExcCount(sal_uInt16 index)
if ((m_numOfEntries > 0) && (index <= m_numOfEntries)) if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
{ {
aCount = readUINT16(m_pIndex[index] + calcMethodParamIndex(readUINT16(m_pIndex[index] + METHOD_OFFSET_PARAM_COUNT))); try {
aCount = readUINT16(m_pIndex[index] + calcMethodParamIndex(readUINT16(m_pIndex[index] + METHOD_OFFSET_PARAM_COUNT)));
} catch (BlopObject::BoundsError &) {
SAL_WARN("registry", "bad data");
}
} }
return aCount; return aCount;
...@@ -1015,15 +1095,18 @@ const sal_Char* MethodList::getMethodExcType(sal_uInt16 index, sal_uInt16 excInd ...@@ -1015,15 +1095,18 @@ const sal_Char* MethodList::getMethodExcType(sal_uInt16 index, sal_uInt16 excInd
if ((m_numOfEntries > 0) && (index <= m_numOfEntries)) if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
{ {
sal_uInt32 excOffset = m_pIndex[index] + calcMethodParamIndex(readUINT16(m_pIndex[index] + METHOD_OFFSET_PARAM_COUNT)); try {
sal_uInt32 excOffset = m_pIndex[index] + calcMethodParamIndex(readUINT16(m_pIndex[index] + METHOD_OFFSET_PARAM_COUNT));
if (excIndex <= readUINT16(excOffset)) if (excIndex <= readUINT16(excOffset))
{ {
aName = m_pCP->readUTF8NameConstant( aName = m_pCP->readUTF8NameConstant(
readUINT16( readUINT16(
excOffset + excOffset +
sizeof(sal_uInt16) + sizeof(sal_uInt16) +
(excIndex * sizeof(sal_uInt16)))); (excIndex * sizeof(sal_uInt16))));
}
} catch (BlopObject::BoundsError &) {
SAL_WARN("registry", "bad data");
} }
} }
...@@ -1036,7 +1119,11 @@ const sal_Char* MethodList::getMethodReturnType(sal_uInt16 index) ...@@ -1036,7 +1119,11 @@ const sal_Char* MethodList::getMethodReturnType(sal_uInt16 index)
if ((m_numOfEntries > 0) && (index <= m_numOfEntries)) if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
{ {
aName = m_pCP->readUTF8NameConstant(readUINT16(m_pIndex[index] + METHOD_OFFSET_RETURN)); try {
aName = m_pCP->readUTF8NameConstant(readUINT16(m_pIndex[index] + METHOD_OFFSET_RETURN));
} catch (BlopObject::BoundsError &) {
SAL_WARN("registry", "bad data");
}
} }
return aName; return aName;
...@@ -1048,7 +1135,11 @@ RTMethodMode MethodList::getMethodMode(sal_uInt16 index) ...@@ -1048,7 +1135,11 @@ RTMethodMode MethodList::getMethodMode(sal_uInt16 index)
if ((m_numOfEntries > 0) && (index <= m_numOfEntries)) if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
{ {
aMode = (RTMethodMode) readUINT16(m_pIndex[index] + METHOD_OFFSET_MODE); try {
aMode = (RTMethodMode) readUINT16(m_pIndex[index] + METHOD_OFFSET_MODE);
} catch (BlopObject::BoundsError &) {
SAL_WARN("registry", "bad data");
}
} }
return aMode; return aMode;
...@@ -1060,7 +1151,11 @@ const sal_Char* MethodList::getMethodDoku(sal_uInt16 index) ...@@ -1060,7 +1151,11 @@ const sal_Char* MethodList::getMethodDoku(sal_uInt16 index)
if ((m_numOfEntries > 0) && (index <= m_numOfEntries)) if ((m_numOfEntries > 0) && (index <= m_numOfEntries))
{ {
aDoku = m_pCP->readUTF8NameConstant(readUINT16(m_pIndex[index] + METHOD_OFFSET_DOKU)); try {
aDoku = m_pCP->readUTF8NameConstant(readUINT16(m_pIndex[index] + METHOD_OFFSET_DOKU));
} catch (BlopObject::BoundsError &) {
SAL_WARN("registry", "bad data");
}
} }
return aDoku; return aDoku;
...@@ -1074,66 +1169,79 @@ const sal_Char* MethodList::getMethodDoku(sal_uInt16 index) ...@@ -1074,66 +1169,79 @@ const sal_Char* MethodList::getMethodDoku(sal_uInt16 index)
class TypeRegistryEntry: public BlopObject { class TypeRegistryEntry: public BlopObject {
public: public:
ConstantPool* m_pCP; std::unique_ptr<ConstantPool> m_pCP;
FieldList* m_pFields; std::unique_ptr<FieldList> m_pFields;
MethodList* m_pMethods; std::unique_ptr<MethodList> m_pMethods;
ReferenceList* m_pReferences; std::unique_ptr<ReferenceList> m_pReferences;
sal_uInt32 m_refCount; sal_uInt32 m_refCount;
sal_uInt16 m_nSuperTypes; sal_uInt16 m_nSuperTypes;
sal_uInt16 m_offset_SUPERTYPES; sal_uInt32 m_offset_SUPERTYPES;
TypeRegistryEntry( TypeRegistryEntry(
const sal_uInt8* buffer, sal_uInt32 len, bool copyBuffer); const sal_uInt8* buffer, sal_uInt32 len, bool copyBuffer);
// throws std::bad_alloc // throws std::bad_alloc
~TypeRegistryEntry();
typereg_Version getVersion() const; typereg_Version getVersion() const;
}; };
TypeRegistryEntry::TypeRegistryEntry( TypeRegistryEntry::TypeRegistryEntry(
const sal_uInt8* buffer, sal_uInt32 len, bool copyBuffer): const sal_uInt8* buffer, sal_uInt32 len, bool copyBuffer):
BlopObject(buffer, len, copyBuffer), m_pCP(NULL), m_pFields(NULL), BlopObject(buffer, len, copyBuffer), m_refCount(1), m_nSuperTypes(0),
m_pMethods(NULL), m_pReferences(NULL), m_refCount(1), m_nSuperTypes(0),
m_offset_SUPERTYPES(0) m_offset_SUPERTYPES(0)
{ {
std::size_t const entrySize = sizeof(sal_uInt16); std::size_t const entrySize = sizeof(sal_uInt16);
sal_uInt16 nHeaderEntries = readUINT16(OFFSET_N_ENTRIES); sal_uInt16 nHeaderEntries = readUINT16(OFFSET_N_ENTRIES);
sal_uInt16 offset_N_SUPERTYPES = OFFSET_N_ENTRIES + entrySize + (nHeaderEntries * entrySize); sal_uInt32 offset_N_SUPERTYPES = OFFSET_N_ENTRIES + entrySize + (nHeaderEntries * entrySize); // cannot overflow
m_offset_SUPERTYPES = offset_N_SUPERTYPES + entrySize; m_offset_SUPERTYPES = offset_N_SUPERTYPES + entrySize; // cannot overflow
m_nSuperTypes = readUINT16(offset_N_SUPERTYPES); m_nSuperTypes = readUINT16(offset_N_SUPERTYPES);
sal_uInt16 offset_CP_SIZE = m_offset_SUPERTYPES + (m_nSuperTypes * entrySize); sal_uInt32 offset_CP_SIZE = m_offset_SUPERTYPES + (m_nSuperTypes * entrySize); // cannot overflow
sal_uInt16 offset_CP = offset_CP_SIZE + entrySize; sal_uInt32 offset_CP = offset_CP_SIZE + entrySize; // cannot overflow
m_pCP = new ConstantPool(m_pBuffer + offset_CP, readUINT16(offset_CP_SIZE)); if (offset_CP > m_bufferLen) {
throw BoundsError();
}
m_pCP.reset(
new ConstantPool(
m_pBuffer + offset_CP, m_bufferLen - offset_CP,
readUINT16(offset_CP_SIZE)));
sal_uInt32 offset = offset_CP + m_pCP->parseIndex(); sal_uInt32 offset = offset_CP + m_pCP->parseIndex(); //TODO: overflow
m_pFields = new FieldList( assert(m_bufferLen >= entrySize);
m_pBuffer + offset + entrySize, readUINT16(offset), m_pCP); if (offset > m_bufferLen - entrySize) {
throw BoundsError();
}
m_pFields.reset(
new FieldList(
m_pBuffer + offset + entrySize, m_bufferLen - (offset + entrySize),
readUINT16(offset), m_pCP.get()));
offset += sizeof(sal_uInt16) + m_pFields->parseIndex(); offset += sizeof(sal_uInt16) + m_pFields->parseIndex(); //TODO: overflow
m_pMethods = new MethodList( assert(m_bufferLen >= entrySize);
m_pBuffer + offset + entrySize, readUINT16(offset), m_pCP); if (offset > m_bufferLen - entrySize) {
throw BoundsError();
}
m_pMethods.reset(
new MethodList(
m_pBuffer + offset + entrySize, m_bufferLen - (offset + entrySize),
readUINT16(offset), m_pCP.get()));
offset += sizeof(sal_uInt16) + m_pMethods->parseIndex(); offset += sizeof(sal_uInt16) + m_pMethods->parseIndex(); //TODO: overflow
m_pReferences = new ReferenceList( assert(m_bufferLen >= entrySize);
m_pBuffer + offset + entrySize, readUINT16(offset), m_pCP); if (offset > m_bufferLen - entrySize) {
throw BoundsError();
}
m_pReferences.reset(
new ReferenceList(
m_pBuffer + offset + entrySize, m_bufferLen - (offset + entrySize),
readUINT16(offset), m_pCP.get()));
m_pReferences->parseIndex(); m_pReferences->parseIndex();
} }
TypeRegistryEntry::~TypeRegistryEntry()
{
delete m_pCP;
delete m_pFields;
delete m_pMethods;
delete m_pReferences;
}
typereg_Version TypeRegistryEntry::getVersion() const { typereg_Version TypeRegistryEntry::getVersion() const {
// Assumes two's complement arithmetic with modulo-semantics: // Assumes two's complement arithmetic with modulo-semantics:
return static_cast< typereg_Version >(readUINT32(OFFSET_MAGIC) - magic); return static_cast< typereg_Version >(readUINT32(OFFSET_MAGIC) - magic);
...@@ -1158,24 +1266,29 @@ REG_DLLPUBLIC sal_Bool TYPEREG_CALLTYPE typereg_reader_create( ...@@ -1158,24 +1266,29 @@ REG_DLLPUBLIC sal_Bool TYPEREG_CALLTYPE typereg_reader_create(
} }
std::unique_ptr< TypeRegistryEntry > entry; std::unique_ptr< TypeRegistryEntry > entry;
try { try {
entry.reset( try {
new TypeRegistryEntry( entry.reset(
static_cast< sal_uInt8 const * >(buffer), new TypeRegistryEntry(
static_cast< sal_uInt32 >(length), copy)); static_cast< sal_uInt8 const * >(buffer),
} catch (std::bad_alloc &) { static_cast< sal_uInt32 >(length), copy));
return false; } catch (std::bad_alloc &) {
} return false;
if (entry->readUINT32(OFFSET_SIZE) != length) { }
*result = 0; if (entry->readUINT32(OFFSET_SIZE) != length) {
return true; *result = 0;
} return true;
typereg_Version version = entry->getVersion(); }
if (version < TYPEREG_VERSION_0 || version > maxVersion) { typereg_Version version = entry->getVersion();;
*result = 0; if (version < TYPEREG_VERSION_0 || version > maxVersion) {
*result = 0;
return true;
}
*result = entry.release();
return true; return true;
} catch (BlopObject::BoundsError &) {
SAL_WARN("registry", "bad data");
return false;
} }
*result = entry.release();
return true;
} }
static TypeReaderImpl TYPEREG_CALLTYPE createEntry(const sal_uInt8* buffer, sal_uInt32 len, sal_Bool copyBuffer) static TypeReaderImpl TYPEREG_CALLTYPE createEntry(const sal_uInt8* buffer, sal_uInt32 len, sal_Bool copyBuffer)
...@@ -1205,84 +1318,103 @@ REG_DLLPUBLIC void TYPEREG_CALLTYPE typereg_reader_release(void * hEntry) SAL_TH ...@@ -1205,84 +1318,103 @@ REG_DLLPUBLIC void TYPEREG_CALLTYPE typereg_reader_release(void * hEntry) SAL_TH
} }
REG_DLLPUBLIC typereg_Version TYPEREG_CALLTYPE typereg_reader_getVersion(void * handle) SAL_THROW_EXTERN_C() { REG_DLLPUBLIC typereg_Version TYPEREG_CALLTYPE typereg_reader_getVersion(void * handle) SAL_THROW_EXTERN_C() {
return handle == 0 if (handle != nullptr) {
? TYPEREG_VERSION_0 try {
: static_cast< TypeRegistryEntry * >(handle)->getVersion(); return static_cast< TypeRegistryEntry * >(handle)->getVersion();
} catch (BlopObject::BoundsError &) {
SAL_WARN("registry", "bad data");
}
}
return TYPEREG_VERSION_0;
} }
static sal_uInt16 TYPEREG_CALLTYPE getMinorVersion(TypeReaderImpl hEntry) static sal_uInt16 TYPEREG_CALLTYPE getMinorVersion(TypeReaderImpl hEntry)
{ {
TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry;
if (pEntry != nullptr) {
if (pEntry == NULL) return 0; try {
return pEntry->readUINT16(OFFSET_MINOR_VERSION);
return pEntry->readUINT16(OFFSET_MINOR_VERSION); } catch (BlopObject::BoundsError &) {
SAL_WARN("registry", "bad data");
}
}
return 0;
} }
static sal_uInt16 TYPEREG_CALLTYPE getMajorVersion(TypeReaderImpl hEntry) static sal_uInt16 TYPEREG_CALLTYPE getMajorVersion(TypeReaderImpl hEntry)
{ {
TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry;
if (pEntry != nullptr) {
if (pEntry == NULL) return 0; try {
return pEntry->readUINT16(OFFSET_MAJOR_VERSION);
return pEntry->readUINT16(OFFSET_MAJOR_VERSION); } catch (BlopObject::BoundsError &) {
SAL_WARN("registry", "bad data");
}
}
return 0;
} }
REG_DLLPUBLIC RTTypeClass TYPEREG_CALLTYPE typereg_reader_getTypeClass(void * hEntry) SAL_THROW_EXTERN_C() REG_DLLPUBLIC RTTypeClass TYPEREG_CALLTYPE typereg_reader_getTypeClass(void * hEntry) SAL_THROW_EXTERN_C()
{ {
TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry;
if (pEntry != nullptr) {
if (pEntry == NULL) return RT_TYPE_INVALID; try {
return (RTTypeClass)
return (RTTypeClass) (pEntry->readUINT16(OFFSET_TYPE_CLASS) & ~RT_TYPE_PUBLISHED);
(pEntry->readUINT16(OFFSET_TYPE_CLASS) & ~RT_TYPE_PUBLISHED); } catch (BlopObject::BoundsError &) {
SAL_WARN("registry", "bad data");
}
}
return RT_TYPE_INVALID;
} }
REG_DLLPUBLIC sal_Bool TYPEREG_CALLTYPE typereg_reader_isPublished(void * hEntry) SAL_THROW_EXTERN_C() REG_DLLPUBLIC sal_Bool TYPEREG_CALLTYPE typereg_reader_isPublished(void * hEntry) SAL_THROW_EXTERN_C()
{ {
TypeRegistryEntry * entry = static_cast< TypeRegistryEntry * >(hEntry); TypeRegistryEntry * entry = static_cast< TypeRegistryEntry * >(hEntry);
return entry != 0 if (entry != nullptr) {
&& (entry->readUINT16(OFFSET_TYPE_CLASS) & RT_TYPE_PUBLISHED) != 0; try {
return (entry->readUINT16(OFFSET_TYPE_CLASS) & RT_TYPE_PUBLISHED) != 0;
} catch (BlopObject::BoundsError &) {
SAL_WARN("registry", "bad data");
}
}
return false;
} }
REG_DLLPUBLIC void TYPEREG_CALLTYPE typereg_reader_getTypeName(void * hEntry, rtl_uString** pTypeName) REG_DLLPUBLIC void TYPEREG_CALLTYPE typereg_reader_getTypeName(void * hEntry, rtl_uString** pTypeName)
SAL_THROW_EXTERN_C() SAL_THROW_EXTERN_C()
{ {
TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry;
if (pEntry != nullptr) {
if (pEntry == NULL) try {
{ const sal_Char* pTmp = pEntry->m_pCP->readUTF8NameConstant(pEntry->readUINT16(OFFSET_THIS_TYPE));
rtl_uString_new(pTypeName); rtl_string2UString(
return; pTypeName, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp),
RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
return;
} catch (BlopObject::BoundsError &) {
SAL_WARN("registry", "bad data");
}
} }
rtl_uString_new(pTypeName);
const sal_Char* pTmp = pEntry->m_pCP->readUTF8NameConstant(pEntry->readUINT16(OFFSET_THIS_TYPE));
rtl_string2UString(
pTypeName, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp),
RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
} }
static void TYPEREG_CALLTYPE getSuperTypeName(TypeReaderImpl hEntry, rtl_uString** pSuperTypeName) static void TYPEREG_CALLTYPE getSuperTypeName(TypeReaderImpl hEntry, rtl_uString** pSuperTypeName)
{ {
TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry;
if (pEntry != nullptr && pEntry->m_nSuperTypes != 0) {
if (pEntry == NULL) try {
{ const sal_Char* pTmp = pEntry->m_pCP->readUTF8NameConstant(pEntry->readUINT16(pEntry->m_offset_SUPERTYPES )); //+ (index * sizeof(sal_uInt16))));
rtl_uString_new(pSuperTypeName); rtl_string2UString(
return; pSuperTypeName, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp),
} RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
return;
if (pEntry->m_nSuperTypes == 0) } catch (BlopObject::BoundsError &) {
{ SAL_WARN("registry", "bad data");
rtl_uString_new(pSuperTypeName); }
return;
} }
rtl_uString_new(pSuperTypeName);
const sal_Char* pTmp = pEntry->m_pCP->readUTF8NameConstant(pEntry->readUINT16(pEntry->m_offset_SUPERTYPES )); //+ (index * sizeof(sal_uInt16))));
rtl_string2UString(
pSuperTypeName, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp),
RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
} }
static void TYPEREG_CALLTYPE getUik(TypeReaderImpl hEntry, RTUik* uik) static void TYPEREG_CALLTYPE getUik(TypeReaderImpl hEntry, RTUik* uik)
...@@ -1291,7 +1423,11 @@ static void TYPEREG_CALLTYPE getUik(TypeReaderImpl hEntry, RTUik* uik) ...@@ -1291,7 +1423,11 @@ static void TYPEREG_CALLTYPE getUik(TypeReaderImpl hEntry, RTUik* uik)
if (pEntry != NULL) if (pEntry != NULL)
{ {
pEntry->m_pCP->readUIK(pEntry->readUINT16(OFFSET_UIK), uik); try {
pEntry->m_pCP->readUIK(pEntry->readUINT16(OFFSET_UIK), uik);
} catch (BlopObject::BoundsError &) {
SAL_WARN("registry", "bad data");
}
} }
} }
...@@ -1299,34 +1435,36 @@ REG_DLLPUBLIC void TYPEREG_CALLTYPE typereg_reader_getDocumentation(void * hEntr ...@@ -1299,34 +1435,36 @@ REG_DLLPUBLIC void TYPEREG_CALLTYPE typereg_reader_getDocumentation(void * hEntr
SAL_THROW_EXTERN_C() SAL_THROW_EXTERN_C()
{ {
TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry;
if (pEntry != nullptr) {
if (pEntry == NULL) try {
{ const sal_Char* pTmp = pEntry->m_pCP->readUTF8NameConstant(pEntry->readUINT16(OFFSET_DOKU));
rtl_uString_new(pDoku); rtl_string2UString(
return; pDoku, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp),
RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
return;
} catch (BlopObject::BoundsError &) {
SAL_WARN("registry", "bad data");
}
} }
rtl_uString_new(pDoku);
const sal_Char* pTmp = pEntry->m_pCP->readUTF8NameConstant(pEntry->readUINT16(OFFSET_DOKU));
rtl_string2UString(
pDoku, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp),
RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
} }
REG_DLLPUBLIC void TYPEREG_CALLTYPE typereg_reader_getFileName(void * hEntry, rtl_uString** pFileName) REG_DLLPUBLIC void TYPEREG_CALLTYPE typereg_reader_getFileName(void * hEntry, rtl_uString** pFileName)
SAL_THROW_EXTERN_C() SAL_THROW_EXTERN_C()
{ {
TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry;
if (pEntry != nullptr) {
if (pEntry == NULL) try {
{ const sal_Char* pTmp = pEntry->m_pCP->readUTF8NameConstant(pEntry->readUINT16(OFFSET_FILENAME));
rtl_uString_new(pFileName); rtl_string2UString(
return; pFileName, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp),
RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
return;
} catch (BlopObject::BoundsError &) {
SAL_WARN("registry", "bad data");
}
} }
rtl_uString_new(pFileName);
const sal_Char* pTmp = pEntry->m_pCP->readUTF8NameConstant(pEntry->readUINT16(OFFSET_FILENAME));
rtl_string2UString(
pFileName, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp),
RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
} }
...@@ -1698,18 +1836,19 @@ REG_DLLPUBLIC void TYPEREG_CALLTYPE typereg_reader_getSuperTypeName( ...@@ -1698,18 +1836,19 @@ REG_DLLPUBLIC void TYPEREG_CALLTYPE typereg_reader_getSuperTypeName(
SAL_THROW_EXTERN_C() SAL_THROW_EXTERN_C()
{ {
TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry; TypeRegistryEntry* pEntry = (TypeRegistryEntry*) hEntry;
if (pEntry != nullptr) {
if (pEntry == NULL) try {
{ OSL_ASSERT(index < pEntry->m_nSuperTypes);
rtl_uString_new(pSuperTypeName); const sal_Char* pTmp = pEntry->m_pCP->readUTF8NameConstant(pEntry->readUINT16(pEntry->m_offset_SUPERTYPES + (index * sizeof(sal_uInt16))));
return; rtl_string2UString(
pSuperTypeName, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp),
RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
return;
} catch (BlopObject::BoundsError &) {
SAL_WARN("registry", "bad data");
}
} }
rtl_uString_new(pSuperTypeName);
OSL_ASSERT(index < pEntry->m_nSuperTypes);
const sal_Char* pTmp = pEntry->m_pCP->readUTF8NameConstant(pEntry->readUINT16(pEntry->m_offset_SUPERTYPES + (index * sizeof(sal_uInt16))));
rtl_string2UString(
pSuperTypeName, pTmp, pTmp == 0 ? 0 : rtl_str_getLength(pTmp),
RTL_TEXTENCODING_UTF8, OSTRING_TO_OUSTRING_CVTFLAGS);
} }
REG_DLLPUBLIC RegistryTypeReader_Api* TYPEREG_CALLTYPE initRegistryTypeReader_Api(void) REG_DLLPUBLIC RegistryTypeReader_Api* TYPEREG_CALLTYPE initRegistryTypeReader_Api(void)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment