diff -r ea891871f481 -r bb5522e88ab2 misc/libphysfs/lzma/CPP/7zip/Archive/Common/ParseProperties.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/misc/libphysfs/lzma/CPP/7zip/Archive/Common/ParseProperties.cpp Mon Apr 10 12:06:43 2017 -0400 @@ -0,0 +1,174 @@ +// ParseProperties.cpp + +#include "StdAfx.h" + +#include "ParseProperties.h" + +#include "Common/StringToInt.h" +#include "Common/MyCom.h" + +HRESULT ParsePropValue(const UString &name, const PROPVARIANT &prop, UInt32 &resValue) +{ + if (prop.vt == VT_UI4) + { + if (!name.IsEmpty()) + return E_INVALIDARG; + resValue = prop.ulVal; + } + else if (prop.vt == VT_EMPTY) + { + if(!name.IsEmpty()) + { + const wchar_t *start = name; + const wchar_t *end; + UInt64 v = ConvertStringToUInt64(start, &end); + if (end - start != name.Length()) + return E_INVALIDARG; + resValue = (UInt32)v; + } + } + else + return E_INVALIDARG; + return S_OK; +} + +static const int kLogarithmicSizeLimit = 32; +static const wchar_t kByteSymbol = L'B'; +static const wchar_t kKiloByteSymbol = L'K'; +static const wchar_t kMegaByteSymbol = L'M'; + +HRESULT ParsePropDictionaryValue(const UString &srcStringSpec, UInt32 &dicSize) +{ + UString srcString = srcStringSpec; + srcString.MakeUpper(); + + const wchar_t *start = srcString; + const wchar_t *end; + UInt64 number = ConvertStringToUInt64(start, &end); + int numDigits = (int)(end - start); + if (numDigits == 0 || srcString.Length() > numDigits + 1) + return E_INVALIDARG; + if (srcString.Length() == numDigits) + { + if (number >= kLogarithmicSizeLimit) + return E_INVALIDARG; + dicSize = (UInt32)1 << (int)number; + return S_OK; + } + switch (srcString[numDigits]) + { + case kByteSymbol: + if (number >= ((UInt64)1 << kLogarithmicSizeLimit)) + return E_INVALIDARG; + dicSize = (UInt32)number; + break; + case kKiloByteSymbol: + if (number >= ((UInt64)1 << (kLogarithmicSizeLimit - 10))) + return E_INVALIDARG; + dicSize = (UInt32)(number << 10); + break; + case kMegaByteSymbol: + if (number >= ((UInt64)1 << (kLogarithmicSizeLimit - 20))) + return E_INVALIDARG; + dicSize = (UInt32)(number << 20); + break; + default: + return E_INVALIDARG; + } + return S_OK; +} + +HRESULT ParsePropDictionaryValue(const UString &name, const PROPVARIANT &prop, UInt32 &resValue) +{ + if (name.IsEmpty()) + { + if (prop.vt == VT_UI4) + { + UInt32 logDicSize = prop.ulVal; + if (logDicSize >= 32) + return E_INVALIDARG; + resValue = (UInt32)1 << logDicSize; + return S_OK; + } + if (prop.vt == VT_BSTR) + return ParsePropDictionaryValue(prop.bstrVal, resValue); + return E_INVALIDARG; + } + return ParsePropDictionaryValue(name, resValue); +} + +bool StringToBool(const UString &s, bool &res) +{ + if (s.IsEmpty() || s.CompareNoCase(L"ON") == 0) + { + res = true; + return true; + } + if (s.CompareNoCase(L"OFF") == 0) + { + res = false; + return true; + } + return false; +} + +HRESULT SetBoolProperty(bool &dest, const PROPVARIANT &value) +{ + switch(value.vt) + { + case VT_EMPTY: + dest = true; + return S_OK; + /* + case VT_UI4: + dest = (value.ulVal != 0); + break; + */ + case VT_BSTR: + return StringToBool(value.bstrVal, dest) ? S_OK : E_INVALIDARG; + } + return E_INVALIDARG; +} + +int ParseStringToUInt32(const UString &srcString, UInt32 &number) +{ + const wchar_t *start = srcString; + const wchar_t *end; + UInt64 number64 = ConvertStringToUInt64(start, &end); + if (number64 > 0xFFFFFFFF) + { + number = 0; + return 0; + } + number = (UInt32)number64; + return (int)(end - start); +} + +HRESULT ParseMtProp(const UString &name, const PROPVARIANT &prop, UInt32 defaultNumThreads, UInt32 &numThreads) +{ + if (name.IsEmpty()) + { + switch(prop.vt) + { + case VT_UI4: + numThreads = prop.ulVal; + break; + default: + { + bool val; + RINOK(SetBoolProperty(val, prop)); + numThreads = (val ? defaultNumThreads : 1); + break; + } + } + } + else + { + UInt32 number; + int index = ParseStringToUInt32(name, number); + if (index != name.Length()) + return E_INVALIDARG; + numThreads = number; + } + return S_OK; +}