Files
codeql/cpp/ql/test/library-tests/dataflow/taint-tests/atl.cpp
2025-08-28 16:54:46 +02:00

1461 lines
37 KiB
C++

namespace {
template<typename T> T source();
template<typename T> T* indirect_source();
void sink(...);
}
typedef unsigned int UINT;
typedef long LONG;
typedef void* LPVOID;
typedef void* PVOID;
typedef bool BOOL;
typedef char* PSTR, *LPSTR;
typedef const char* LPCTSTR;
typedef const wchar_t* LPCWSTR;
typedef unsigned short WORD;
typedef unsigned long DWORD;
typedef void* HANDLE;
typedef LONG HRESULT;
typedef unsigned long ULONG;
typedef const char* LPCSTR;
typedef wchar_t OLECHAR;
typedef OLECHAR* LPOLESTR;
typedef const LPOLESTR LPCOLESTR;
typedef OLECHAR* BSTR;
typedef wchar_t* LPWSTR, *PWSTR;
typedef BSTR* LPBSTR;
typedef unsigned short USHORT;
typedef char *LPTSTR;
struct __POSITION { int unused; };
typedef __POSITION* POSITION;
typedef WORD ATL_URL_PORT;
using HINSTANCE = void*;
using size_t = decltype(sizeof(int));
using SIZE_T = size_t;
#define NULL nullptr
namespace ATL {
enum ATL_URL_SCHEME{
ATL_URL_SCHEME_UNKNOWN = -1,
ATL_URL_SCHEME_FTP = 0,
ATL_URL_SCHEME_GOPHER = 1,
ATL_URL_SCHEME_HTTP = 2,
ATL_URL_SCHEME_HTTPS = 3,
ATL_URL_SCHEME_FILE = 4,
ATL_URL_SCHEME_NEWS = 5,
ATL_URL_SCHEME_MAILTO = 6,
ATL_URL_SCHEME_SOCKS = 7
};
typedef struct tagSAFEARRAYBOUND {
ULONG cElements;
LONG lLbound;
} SAFEARRAYBOUND, *LPSAFEARRAYBOUND;
typedef struct tagVARIANT {
/* ... */
} VARIANT;
typedef struct tagSAFEARRAY {
USHORT cDims;
USHORT fFeatures;
ULONG cbElements;
ULONG cLocks;
PVOID pvData;
SAFEARRAYBOUND rgsabound[1];
} SAFEARRAY, *LPSAFEARRAY;
struct _U_STRINGorID {
_U_STRINGorID(UINT nID);
_U_STRINGorID(LPCTSTR lpString);
LPCTSTR m_lpstr;
};
void test__U_STRINGorID() {
{
UINT x = source<UINT>();
_U_STRINGorID u(x);
sink(u.m_lpstr); // $ ir
}
{
LPCTSTR y = indirect_source<const char>();
_U_STRINGorID u(y);
sink(u.m_lpstr); // $ ir
}
}
template <int t_nBufferLength>
struct CA2AEX {
LPSTR m_psz;
char m_szBuffer[t_nBufferLength];
CA2AEX(LPCSTR psz, UINT nCodePage);
CA2AEX(LPCSTR psz);
~CA2AEX();
operator LPSTR() const throw();
};
void test_CA2AEX() {
{
LPSTR x = indirect_source<char>();
CA2AEX<128> a(x);
sink(static_cast<LPSTR>(a)); // $ ir
sink(a.m_psz); // $ ir
sink(a.m_szBuffer); // $ ir
}
{
LPSTR x = indirect_source<char>();
CA2AEX<128> a(x, 0);
sink(static_cast<LPSTR>(a)); // $ ir
sink(a.m_psz); // $ ir
sink(a.m_szBuffer); // $ ir
}
}
template<int t_nBufferLength>
struct CA2CAEX {
CA2CAEX(LPCSTR psz, UINT nCodePage) ;
CA2CAEX(LPCSTR psz) ;
~CA2CAEX() throw();
operator LPCSTR() const throw();
LPCSTR m_psz;
};
void test_CA2CAEX() {
LPCSTR x = indirect_source<char>();
{
CA2CAEX<128> a(x);
sink(static_cast<LPCSTR>(a)); // $ ir
sink(a.m_psz); // $ ir
sink(a.m_psz); // $ ir
}
{
CA2CAEX<128> a(x, 0);
sink(static_cast<LPCSTR>(a)); // $ ir
sink(a.m_psz); // $ ir
sink(a.m_psz); // $ ir
}
}
template <int t_nBufferLength>
struct CA2WEX {
CA2WEX(LPCSTR psz, UINT nCodePage) ;
CA2WEX(LPCSTR psz) ;
~CA2WEX() throw();
operator LPWSTR() const throw();
LPWSTR m_psz;
wchar_t m_szBuffer[t_nBufferLength];
};
void test_CA2WEX() {
LPCSTR x = indirect_source<char>();
{
CA2WEX<128> a(x);
sink(static_cast<LPWSTR>(a)); // $ ir
sink(a.m_psz); // $ ir
sink(a.m_psz); // $ ir
}
{
CA2WEX<128> a(x, 0);
sink(static_cast<LPWSTR>(a)); // $ ir
sink(a.m_psz); // $ ir
sink(a.m_psz); // $ ir
}
}
template<typename T>
struct CElementTraitsBase {
typedef const T& INARGTYPE;
typedef T& OUTARGTYPE;
static void CopyElements(T* pDest, const T* pSrc, size_t nElements);
static void RelocateElements(T* pDest, T* pSrc, size_t nElements);
};
template <typename T>
struct CDefaultElementTraits : public CElementTraitsBase<T> {};
template<typename T>
struct CElementTraits : public CDefaultElementTraits<T> {};
template<typename E, class ETraits = CElementTraits<E>>
struct CAtlArray {
using INARGTYPE = typename ETraits::INARGTYPE;
using OUTARGTYPE = typename ETraits::OUTARGTYPE;
CAtlArray() throw();
~CAtlArray() throw();
size_t Add(INARGTYPE element);
size_t Add();
size_t Append(const CAtlArray<E, ETraits>& aSrc);
void Copy(const CAtlArray<E, ETraits>& aSrc);
const E& GetAt(size_t iElement) const throw();
E& GetAt(size_t iElement) throw();
size_t GetCount() const throw();
E* GetData() throw();
const E* GetData() const throw();
void InsertArrayAt(size_t iStart, const CAtlArray<E, ETraits>* paNew);
void InsertAt(size_t iElement, INARGTYPE element, size_t nCount);
bool IsEmpty() const throw();
void RemoveAll() throw();
void RemoveAt(size_t iElement, size_t nCount);
void SetAt(size_t iElement, INARGTYPE element);
void SetAtGrow(size_t iElement, INARGTYPE element);
bool SetCount(size_t nNewSize, int nGrowBy);
E& operator[](size_t ielement) throw();
const E& operator[](size_t ielement) const throw();
};
void test_CAtlArray() {
int x = source<int>();
{
CAtlArray<int> a;
a.Add(x);
sink(a[0]); // $ ir
a.Add(0);
sink(a[0]); // $ ir
CAtlArray<int> a2;
sink(a2[0]);
a2.Append(a);
sink(a2[0]); // $ ir
CAtlArray<int> a3;
sink(a3[0]);
a3.Copy(a2);
sink(a3[0]); // $ ir
sink(a3.GetAt(0)); // $ ir
sink(*a3.GetData()); // $ ir
CAtlArray<int> a4;
sink(a4.GetAt(0));
a4.InsertArrayAt(0, &a3);
sink(a4.GetAt(0)); // $ ir
}
{
CAtlArray<int> a5;
a5.InsertAt(0, source<int>(), 1);
sink(a5[0]); // $ ir
CAtlArray<int> a6;
a6.SetAtGrow(0, source<int>());
sink(a6[0]); // $ ir
}
}
template<typename E, class ETraits = CElementTraits<E>>
struct CAtlList {
using INARGTYPE = typename ETraits::INARGTYPE;
CAtlList(UINT nBlockSize) throw();
~CAtlList() throw();
POSITION AddHead();
POSITION AddHead(INARGTYPE element);
void AddHeadList(const CAtlList<E, ETraits>* plNew);
POSITION AddTail();
POSITION AddTail(INARGTYPE element);
void AddTailList(const CAtlList<E, ETraits>* plNew);
POSITION Find(INARGTYPE element, POSITION posStartAfter) const throw();
POSITION FindIndex(size_t iElement) const throw();
E& GetAt(POSITION pos) throw();
const E& GetAt(POSITION pos) const throw();
size_t GetCount() const throw();
E& GetHead() throw();
const E& GetHead() const throw();
POSITION GetHeadPosition() const throw();
E& GetNext(POSITION& pos) throw();
const E& GetNext(POSITION& pos) const throw();
E& GetPrev(POSITION& pos) throw();
const E& GetPrev(POSITION& pos) const throw();
E& GetTail() throw();
const E& GetTail() const throw();
POSITION GetTailPosition() const throw();
POSITION InsertAfter(POSITION pos, INARGTYPE element);
POSITION InsertBefore(POSITION pos, INARGTYPE element);
bool IsEmpty() const throw();
void MoveToHead(POSITION pos) throw();
void MoveToTail(POSITION pos) throw();
void RemoveAll() throw();
void RemoveAt(POSITION pos) throw();
E RemoveHead();
void RemoveHeadNoReturn() throw();
E RemoveTail();
void RemoveTailNoReturn() throw();
void SetAt(POSITION pos, INARGTYPE element);
void SwapElements(POSITION pos1, POSITION pos2) throw();
};
void test_CAtlList() {
int x = source<int>();
{
CAtlList<int> list(10);
sink(list.GetHead());
list.AddHead(x);
sink(list.GetHead()); // $ ir
CAtlList<int> list2(10);
list2.AddHeadList(&list);
sink(list2.GetHead()); // $ ir
CAtlList<int> list3(10);
list3.AddTail(x);
sink(list3.GetHead()); // $ ir
CAtlList<int> list4(10);
list4.AddTailList(&list3);
sink(list4.GetHead()); // $ ir
{
CAtlList<int> list5(10);
auto pos = list5.Find(x, list5.GetHeadPosition());
sink(list5.GetAt(pos)); // $ MISSING: ir
}
{
CAtlList<int> list6(10);
list6.AddHead(x);
auto pos = list6.FindIndex(0);
sink(list6.GetAt(pos)); // $ ir
}
{
CAtlList<int> list7(10);
auto pos = list7.GetTailPosition();
list7.InsertAfter(pos, x);
sink(list7.GetHead()); // $ ir
}
{
CAtlList<int> list8(10);
auto pos = list8.GetTailPosition();
list8.InsertBefore(pos, x);
sink(list8.GetHead()); // $ ir
}
{
CAtlList<int> list9(10);
list9.SetAt(list9.GetHeadPosition(), x);
sink(list9.GetHead()); // $ ir
}
}
int* p = indirect_source<int>();
{
CAtlList<int*> list(10);
sink(list.GetHead());
list.AddHead(p);
sink(list.GetHead()); // $ ir
CAtlList<int*> list2(10);
list2.AddHeadList(&list);
sink(list2.GetHead()); // $ ir
CAtlList<int*> list3(10);
list3.AddTail(p);
sink(list3.GetHead()); // $ ir
CAtlList<int*> list4(10);
list4.AddTailList(&list3);
sink(list4.GetHead()); // $ ir
{
CAtlList<int*> list5(10);
auto pos = list5.Find(p, list5.GetHeadPosition());
sink(list5.GetAt(pos)); // $ MISSING: ir
}
{
CAtlList<int*> list6(10);
list6.AddHead(p);
auto pos = list6.FindIndex(0);
sink(list6.GetAt(pos)); // $ ir
}
{
CAtlList<int*> list7(10);
auto pos = list7.GetTailPosition();
list7.InsertAfter(pos, p);
sink(list7.GetHead()); // $ ir
}
{
CAtlList<int*> list8(10);
auto pos = list8.GetTailPosition();
list8.InsertBefore(pos, p);
sink(list8.GetHead()); // $ ir
}
{
CAtlList<int*> list9(10);
list9.SetAt(list9.GetHeadPosition(), p);
sink(list9.GetHead()); // $ ir
}
}
}
struct IUnknown { };
struct ISequentialStream : public IUnknown { };
struct IStream : public ISequentialStream { };
struct CComBSTR {
CComBSTR() throw();
CComBSTR(const CComBSTR& src);
CComBSTR(int nSize);
CComBSTR(int nSize, LPCOLESTR sz);
CComBSTR(int nSize, LPCSTR sz);
CComBSTR(LPCOLESTR pSrc);
CComBSTR(LPCSTR pSrc);
CComBSTR(CComBSTR&& src) throw();
~CComBSTR();
HRESULT Append(const CComBSTR& bstrSrc) throw();
HRESULT Append(wchar_t ch) throw();
HRESULT Append(char ch) throw();
HRESULT Append(LPCOLESTR lpsz) throw();
HRESULT Append(LPCSTR lpsz) throw();
HRESULT Append(LPCOLESTR lpsz, int nLen) throw();
HRESULT AppendBSTR(BSTR p) throw();
HRESULT AppendBytes(const char* lpsz, int nLen) throw();
HRESULT ArrayToBSTR(const SAFEARRAY* pSrc) throw();
HRESULT AssignBSTR(const BSTR bstrSrc) throw();
void Attach(BSTR src) throw();
HRESULT BSTRToArray(LPSAFEARRAY* ppArray) throw();
unsigned int ByteLength() const throw();
BSTR Copy() const throw();
HRESULT CopyTo(BSTR* pbstr) throw();
HRESULT CopyTo(VARIANT* pvarDest) throw();
BSTR Detach() throw();
void Empty() throw();
unsigned int Length() const throw();
bool LoadString(HINSTANCE hInst, UINT nID) throw();
bool LoadString(UINT nID) throw();
HRESULT ReadFromStream(IStream* pStream) throw();
HRESULT ToUpper() throw();
HRESULT WriteToStream(IStream* pStream) throw();
operator BSTR() const throw();
BSTR* operator&() throw();
CComBSTR& operator+= (const CComBSTR& bstrSrc);
CComBSTR& operator+= (const LPCOLESTR pszSrc);
BSTR m_str;
};
LPSAFEARRAY getSafeArray() {
SAFEARRAY* safe = new SAFEARRAY;
safe->pvData = indirect_source<char>();
return safe;
}
void test_CComBSTR() {
char* x = indirect_source<char>();
{
CComBSTR b(x);
sink(b.m_str); // $ ir
CComBSTR b2(b);
sink(b2.m_str); // $ ir
}
{
CComBSTR b(10, x);
sink(b.m_str); // $ ir
}
{
CComBSTR b(x);
CComBSTR b2;
sink(b2.m_str);
b2 += b;
sink(b2.m_str); // $ ir
CComBSTR b3;
b3 += x;
sink(b3.m_str); // $ ir
sink(static_cast<BSTR>(b3)); // $ ir
sink(**&b3); // $ ir
CComBSTR b4;
b4.Append(source<char>());
sink(b4.m_str); // $ ir
CComBSTR b5;
b5.AppendBSTR(b4.m_str);
sink(b5.m_str); // $ ir
CComBSTR b6;
b6.AppendBytes(x, 10);
sink(b6.m_str); // $ ir
CComBSTR b7;
b7.ArrayToBSTR(getSafeArray());
sink(b7.m_str); // $ ir
CComBSTR b8;
b8.AssignBSTR(b7.m_str);
sink(b8.m_str); // $ ir
CComBSTR b9;
LPSAFEARRAY safe;
b9.Append(source<char>());
b9.BSTRToArray(&safe);
sink(safe->pvData); // $ ir
sink(b9.Copy()); // $ ir
}
wchar_t* w = indirect_source<wchar_t>();
{
CComBSTR b(w);
sink(b.m_str); // $ ir
CComBSTR b2;
b2.Attach(w);
sink(b2.m_str); // $ ir
}
{
CComBSTR b(10, w);
sink(b.m_str); // $ ir
}
}
template <typename T>
struct CComSafeArray {
CComSafeArray();
CComSafeArray(const SAFEARRAYBOUND& bound);
CComSafeArray(ULONG ulCount, LONG lLBound);
CComSafeArray(const SAFEARRAYBOUND* pBound, UINT uDims);
CComSafeArray(const CComSafeArray& saSrc);
CComSafeArray(const SAFEARRAY& saSrc);
CComSafeArray(const SAFEARRAY* psaSrc);
~CComSafeArray() throw();
HRESULT Add(const SAFEARRAY* psaSrc);
HRESULT Add(ULONG ulCount, const T* pT, BOOL bCopy);
HRESULT Add(const T& t, BOOL bCopy);
HRESULT Attach(const SAFEARRAY* psaSrc);
HRESULT CopyFrom(LPSAFEARRAY* ppArray);
HRESULT CopyTo(LPSAFEARRAY* ppArray);
HRESULT Create(const SAFEARRAYBOUND* pBound, UINT uDims);
HRESULT Create(ULONG ulCount, LONG lLBound);
HRESULT Destroy();
LPSAFEARRAY Detach();
T& GetAt(LONG lIndex) const;
ULONG GetCount(UINT uDim) const;
UINT GetDimensions() const;
LONG GetLowerBound(UINT uDim) const;
LPSAFEARRAY GetSafeArrayPtr() throw();
LONG GetUpperBound(UINT uDim) const;
bool IsSizable() const;
HRESULT MultiDimGetAt(const LONG* alIndex, T& t);
HRESULT MultiDimSetAt(const LONG* alIndex, const T& t);
HRESULT Resize(const SAFEARRAYBOUND* pBound);
HRESULT Resize(ULONG ulCount, LONG lLBound);
HRESULT SetAt(LONG lIndex, const T& t, BOOL bCopy);
operator LPSAFEARRAY() const;
T& operator[](long lindex) const;
T& operator[](int nindex) const;
LPSAFEARRAY m_psa;
};
void test_CComSafeArray() {
LPSAFEARRAY safe = getSafeArray();
sink(safe->pvData); // $ ir
{
CComSafeArray<int> c(safe);
sink(c[0]); // $ ir
sink(c.GetAt(0)); // $ ir
sink(c.GetSafeArrayPtr()->pvData); // $ ir
sink(c.m_psa->pvData); // $ ir
}
{
CComSafeArray<int> c;
sink(c[0]);
sink(c.GetAt(0));
sink(c.GetSafeArrayPtr()->pvData);
c.Add(safe);
sink(c[0]); // $ ir
sink(c.GetAt(0)); // $ ir
sink(c.GetSafeArrayPtr()->pvData); // $ ir
sink(static_cast<LPSAFEARRAY>(c)->pvData); // $ ir
}
{
CComSafeArray<int> c;
c.Add(source<int>(), true);
sink(c[0]); // $ ir
sink(c.GetAt(0)); // $ ir
sink(c.GetSafeArrayPtr()->pvData); // $ ir
}
{
CComSafeArray<int> c;
c.SetAt(0, source<int>(), true);
sink(c[0]); // $ ir
sink(c[0L]); // $ ir
}
}
template <typename StringType>
struct CPathT {
typedef StringType PCXSTR; // simplified
CPathT(PCXSTR pszPath);
CPathT(const CPathT<StringType>& path);
CPathT() throw();
void AddBackslash();
BOOL AddExtension(PCXSTR pszExtension);
BOOL Append(PCXSTR pszMore);
void BuildRoot(int iDrive);
void Canonicalize();
void Combine(PCXSTR pszDir, PCXSTR pszFile);
CPathT<StringType> CommonPrefix(PCXSTR pszOther);
BOOL CompactPathEx(UINT nMaxChars, DWORD dwFlags);
BOOL FileExists() const;
int FindExtension() const;
int FindFileName() const;
int GetDriveNumber() const;
StringType GetExtension() const;
BOOL IsDirectory() const;
BOOL IsFileSpec() const;
BOOL IsPrefix(PCXSTR pszPrefix) const;
BOOL IsRelative() const;
BOOL IsRoot() const;
BOOL IsSameRoot(PCXSTR pszOther) const;
BOOL IsUNC() const;
BOOL IsUNCServer() const;
BOOL IsUNCServerShare() const;
BOOL MakePretty();
BOOL MatchSpec(PCXSTR pszSpec) const;
void QuoteSpaces();
BOOL RelativePathTo(
PCXSTR pszFrom,
DWORD dwAttrFrom,
PCXSTR pszTo,
DWORD dwAttrTo);
void RemoveArgs();
void RemoveBackslash();
void RemoveBlanks();
void RemoveExtension();
BOOL RemoveFileSpec();
BOOL RenameExtension(PCXSTR pszExtension);
int SkipRoot() const;
void StripPath();
BOOL StripToRoot();
void UnquoteSpaces();
operator const StringType&() const throw();
operator PCXSTR() const throw();
operator StringType&() throw();
CPathT<StringType>& operator+=(PCXSTR pszMore);
StringType m_strPath;
};
using CPath = CPathT<char*>;
void test_CPathT() {
char* x = indirect_source<char>();
CPath p(x);
sink(static_cast<char*>(p)); // $ MISSING: ir
sink(p.m_strPath); // $ ir
CPath p2(p);
sink(p2.m_strPath); // $ ir
{
CPath p;
p.AddExtension(x);
sink(p.m_strPath); // $ ir
}
{
CPath p;
p.Append(x);
sink(p.m_strPath); // $ ir
CPath p2;
p2 += p;
sink(p2.m_strPath); // $ MISSING: ir // this requires flow through `operator StringType&()` which we can't yet model in MaD
CPath p3;
p3 += x;
sink(p3.m_strPath); // $ ir
}
{
CPath p;
p.Combine(x, nullptr);
sink(p.m_strPath); // $ ir
}
{
CPath p;
p.Combine(nullptr, x);
sink(p.m_strPath); // $ ir
}
{
CPath p;
auto p2 = p.CommonPrefix(x);
sink(p2.m_strPath); // $ ir
sink(p2.GetExtension()); // $ ir
}
}
template <class T>
struct CSimpleArray {
CSimpleArray(const CSimpleArray<T>& src);
CSimpleArray();
~CSimpleArray();
BOOL Add(const T& t);
int Find(const T& t) const;
T* GetData() const;
int GetSize() const;
BOOL Remove(const T& t);
void RemoveAll();
BOOL RemoveAt(int nIndex);
BOOL SetAtIndex(
int nIndex,
const T& t);
T& operator[](int nindex);
CSimpleArray<T> & operator=(const CSimpleArray<T>& src);
};
void test_CSimpleArray() {
int x = source<int>();
{
CSimpleArray<int> a;
a.Add(x);
sink(a[0]); // $ ir
a.Add(0);
sink(a[0]); // $ ir
CSimpleArray<int> a2;
sink(a2[0]);
a2 = a;
sink(a2[0]); // $ ir
}
{
CSimpleArray<int> a;
a.Add(x);
sink(a.GetData()); // $ ir
CSimpleArray<int> a2;
int pos = a2.Find(x);
sink(a2[pos]); // $ MISSING: ir
}
}
template <class TKey, class TVal>
struct CSimpleMap {
CSimpleMap();
~CSimpleMap();
BOOL Add(const TKey& key, const TVal& val);
int FindKey(const TKey& key) const;
int FindVal(const TVal& val) const;
TKey& GetKeyAt(int nIndex) const;
int GetSize() const;
TVal& GetValueAt(int nIndex) const;
TVal Lookup(const TKey& key) const;
BOOL Remove(const TKey& key);
void RemoveAll();
BOOL RemoveAt(int nIndex);
TKey ReverseLookup(const TVal& val) const;
BOOL SetAt(const TKey& key, const TVal& val);
BOOL SetAtIndex(int nIndex, const TKey& key, const TVal& val);
};
void test_CSimpleMap() {
wchar_t* x = source<wchar_t*>();
{
CSimpleMap<char*, wchar_t*> a;
a.Add("hello", x);
sink(a.Lookup("hello")); // $ ir
}
{
CSimpleMap<char*, wchar_t*> a;
auto pos = a.FindKey("hello");
sink(a.GetValueAt(pos)); // clean
}
{
CSimpleMap<char*, wchar_t*> a;
auto pos = a.FindVal(x);
sink(a.GetValueAt(pos)); // $ MISSING: ir
}
{
CSimpleMap<char*, wchar_t*> a;
auto key = a.ReverseLookup(x);
sink(key);
sink(a.Lookup(key)); // $ MISSING: ir
}
{
CSimpleMap<char*, wchar_t*> a;
a.SetAt("hello", x);
sink(a.Lookup("hello")); // $ ir
}
{
CSimpleMap<char*, wchar_t*> a;
a.SetAtIndex(0, "hello", x);
sink(a.Lookup("hello")); // $ ir
}
}
struct CUrl {
CUrl& operator= (const CUrl& urlThat) throw();
CUrl() throw();
CUrl(const CUrl& urlThat) throw();
~CUrl() throw();
inline BOOL Canonicalize(DWORD dwFlags) throw();
inline void Clear() throw();
BOOL CrackUrl(LPCTSTR lpszUrl, DWORD dwFlags) throw();
inline BOOL CreateUrl(LPTSTR lpszUrl, DWORD* pdwMaxLength, DWORD dwFlags) const throw();
inline LPCTSTR GetExtraInfo() const throw();
inline DWORD GetExtraInfoLength() const throw();
inline LPCTSTR GetHostName() const throw();
inline DWORD GetHostNameLength() const throw();
inline LPCTSTR GetPassword() const throw();
inline DWORD GetPasswordLength() const throw();
inline ATL_URL_PORT GetPortNumber() const throw();
inline ATL_URL_SCHEME GetScheme() const throw();
inline LPCTSTR GetSchemeName() const throw();
inline DWORD GetSchemeNameLength() const throw();
inline DWORD GetUrlLength() const throw();
inline LPCTSTR GetUrlPath() const throw();
inline DWORD GetUrlPathLength() const throw();
inline LPCTSTR GetUserName() const throw();
inline DWORD GetUserNameLength() const throw();
inline BOOL SetExtraInfo(LPCTSTR lpszInfo) throw();
inline BOOL SetHostName(LPCTSTR lpszHost) throw();
inline BOOL SetPassword(LPCTSTR lpszPass) throw();
inline BOOL SetPortNumber(ATL_URL_PORT nPrt) throw();
inline BOOL SetScheme(ATL_URL_SCHEME nScheme) throw();
inline BOOL SetSchemeName(LPCTSTR lpszSchm) throw();
inline BOOL SetUrlPath(LPCTSTR lpszPath) throw();
inline BOOL SetUserName(LPCTSTR lpszUser) throw();
};
void test_CUrl() {
char* x = indirect_source<char>();
CUrl url;
url.CrackUrl(x, 0);
sink(url); // $ ir
sink(url.GetExtraInfo()); // $ ir
sink(url.GetHostName()); // $ ir
sink(url.GetPassword()); // $ ir
sink(url.GetSchemeName()); // $ ir
sink(url.GetUrlPath()); // $ ir
sink(url.GetUserName()); // $ ir
{
CUrl url2;
DWORD len;
char buffer[1024];
url2.CrackUrl(x, 0);
url2.CreateUrl(buffer, &len, 0);
sink(buffer); // $ ast ir
}
{
CUrl url2;
url2.SetExtraInfo(x);
sink(url2); // $ ir
}
{
CUrl url2;
url2.SetHostName(x);
sink(url2); // $ ir
}
{
CUrl url2;
url2.SetPassword(x);
sink(url2); // $ ir
}
{
CUrl url2;
url2.SetSchemeName(x);
sink(url2); // $ ir
}
{
CUrl url2;
url2.SetUrlPath(x);
sink(url2); // $ ir
}
{
CUrl url2;
url2.SetUserName(x);
sink(url2); // $ ir
}
}
struct IAtlStringMgr {}; // simplified
using XCHAR = char;
using YCHAR = wchar_t;
template <typename BaseType>
struct CSimpleStringT {
using PCXSTR = const BaseType*; // simplified
using PXSTR = BaseType*; // simplified
CSimpleStringT() throw();
CSimpleStringT(const XCHAR* pchSrc, int nLength, IAtlStringMgr* pStringMgr);
CSimpleStringT(PCXSTR pszSrc, IAtlStringMgr* pStringMgr);
CSimpleStringT(const CSimpleStringT& strSrc);
~CSimpleStringT() throw();
void Append(const CSimpleStringT& strSrc);
void Append(PCXSTR pszSrc, int nLength);
void Append(PCXSTR pszSrc);
void AppendChar(XCHAR ch);
static void CopyChars(XCHAR* pchDest, const XCHAR* pchSrc, int nChars) throw();
static void CopyChars(XCHAR* pchDest, size_t nDestLen, const XCHAR* pchSrc, int nChars) throw();
static void CopyCharsOverlapped(XCHAR* pchDest, const XCHAR* pchSrc, int nChars) throw();
XCHAR GetAt(int iChar) const;
PXSTR GetBuffer(int nMinBufferLength);
PXSTR GetBuffer();
PXSTR GetBufferSetLength(int nLength);
PCXSTR GetString() const throw();
PXSTR LockBuffer();
void SetAt(int iChar, XCHAR ch);
void SetString(PCXSTR pszSrc, int nLength);
void SetString(PCXSTR pszSrc);
operator PCXSTR() const throw();
XCHAR operator[](int iChar) const;
CSimpleStringT& operator+=(PCXSTR pszSrc);
CSimpleStringT& operator+=(const CSimpleStringT& strSrc);
CSimpleStringT& operator+=(char ch);
CSimpleStringT& operator+=(unsigned char ch);
CSimpleStringT& operator+=(wchar_t ch);
CSimpleStringT& operator=(PCXSTR pszSrc);
CSimpleStringT& operator=(const CSimpleStringT& strSrc);
};
void test_CSimpleStringT() {
char* x = indirect_source<char>();
CSimpleStringT<char> s1(x, 10, nullptr);
sink(s1.GetString()); // $ ir
CSimpleStringT<char> s2(x, nullptr);
sink(s2.GetString()); // $ ir
CSimpleStringT<char> s3(s2);
sink(s3.GetString()); // $ ir
CSimpleStringT<char> s4;
s4.Append(indirect_source<char>());
sink(s4.GetString()); // $ ir
CSimpleStringT<char> s5;
s5.Append(s4);
sink(s5.GetString()); // $ ir
CSimpleStringT<char> s6;
s6.Append(indirect_source<char>(), 42);
sink(s6.GetString()); // $ ir
char buffer1[128];
CSimpleStringT<char>::CopyChars(buffer1, x, 10);
sink(buffer1); // $ ast ir
char buffer2[128];
CSimpleStringT<char>::CopyChars(buffer2, 128, x, 10);
sink(buffer2); // $ ast ir
char buffer3[128];
CSimpleStringT<char>::CopyCharsOverlapped(buffer3, x, 10);
sink(buffer3); // $ ast ir
sink(s4.GetAt(0)); // $ ir
sink(s4.GetBuffer(10)); // $ ir
sink(s4.GetBuffer()); // $ ir
sink(s4.GetBufferSetLength(10)); // $ ir
sink(s4.LockBuffer()); // $ ir
CSimpleStringT<char> s7;
s7.SetAt(0, source<char>());
sink(s7.GetAt(0)); // $ ir
CSimpleStringT<char> s8;
s8.SetString(indirect_source<char>());
sink(s8.GetAt(0)); // $ ir
CSimpleStringT<char> s9;
s9.SetString(indirect_source<char>(), 1024);
sink(s9.GetAt(0)); // $ ir
sink(static_cast<CSimpleStringT<char>::PCXSTR>(s1)); // $ ir
sink(s1[0]); // $ ir
}
template<typename T>
struct MakeOther {};
template<>
struct MakeOther<char> {
using other_t = wchar_t;
};
template<>
struct MakeOther<wchar_t> {
using other_t = char;
};
template<typename BaseType>
struct CStringT : public CSimpleStringT<BaseType> {
using XCHAR = BaseType; // simplified
using YCHAR = typename MakeOther<BaseType>::other_t; // simplified
using PCXSTR = typename CSimpleStringT<BaseType>::PCXSTR;
using PXSTR = typename CSimpleStringT<BaseType>::PXSTR;
CStringT() throw();
CStringT(IAtlStringMgr* pStringMgr) throw();
CStringT(const VARIANT& varSrc);
CStringT(const VARIANT& varSrc, IAtlStringMgr* pStringMgr);
CStringT(const CStringT& strSrc);
CStringT(const CSimpleStringT<BaseType>& strSrc);
CStringT(const XCHAR* pszSrc);
CStringT(const YCHAR* pszSrc);
CStringT(LPCSTR pszSrc, IAtlStringMgr* pStringMgr);
CStringT(LPCWSTR pszSrc, IAtlStringMgr* pStringMgr);
CStringT(const unsigned char* pszSrc);
CStringT(char* pszSrc);
CStringT(unsigned char* pszSrc);
CStringT(wchar_t* pszSrc);
CStringT(const unsigned char* pszSrc, IAtlStringMgr* pStringMgr);
CStringT(char ch, int nLength = 1);
CStringT(wchar_t ch, int nLength = 1);
CStringT(const XCHAR* pch, int nLength);
CStringT(const YCHAR* pch, int nLength);
CStringT(const XCHAR* pch, int nLength, IAtlStringMgr* pStringMgr);
CStringT(const YCHAR* pch, int nLength, IAtlStringMgr* pStringMgr);
operator CSimpleStringT<BaseType> &();
~CStringT() throw();
BSTR AllocSysString() const;
void AppendFormat(PCXSTR pszFormat, ...);
void AppendFormat(UINT nFormatID, ...);
int Delete(int iIndex, int nCount = 1);
int Find(PCXSTR pszSub, int iStart=0) const throw();
int Find(XCHAR ch, int iStart=0) const throw();
int FindOneOf(PCXSTR pszCharSet) const throw();
void Format(UINT nFormatID, ...);
void Format(PCXSTR pszFormat, ...);
BOOL GetEnvironmentVariable(PCXSTR pszVar);
int Insert(int iIndex, PCXSTR psz);
int Insert(int iIndex, XCHAR ch);
CStringT Left(int nCount) const;
BOOL LoadString(HINSTANCE hInstance, UINT nID, WORD wLanguageID);
BOOL LoadString(HINSTANCE hInstance, UINT nID);
BOOL LoadString(UINT nID);
CStringT& MakeLower();
CStringT& MakeReverse();
CStringT& MakeUpper();
CStringT Mid(int iFirst, int nCount) const;
CStringT Mid(int iFirst) const;
int Replace(PCXSTR pszOld, PCXSTR pszNew);
int Replace(XCHAR chOld, XCHAR chNew);
CStringT Right(int nCount) const;
BSTR SetSysString(BSTR* pbstr) const;
CStringT SpanExcluding(PCXSTR pszCharSet) const;
CStringT SpanIncluding(PCXSTR pszCharSet) const;
CStringT Tokenize(PCXSTR pszTokens, int& iStart) const;
CStringT& Trim(XCHAR chTarget);
CStringT& Trim(PCXSTR pszTargets);
CStringT& Trim();
CStringT& TrimLeft(XCHAR chTarget);
CStringT& TrimLeft(PCXSTR pszTargets);
CStringT& TrimLeft();
CStringT& TrimRight(XCHAR chTarget);
CStringT& TrimRight(PCXSTR pszTargets);
CStringT& TrimRight();
};
void test_CStringT() {
VARIANT v = source<VARIANT>();
CStringT<char> s1(v);
sink(s1.GetString()); // $ ir
CStringT<char> s2(v, nullptr);
sink(s2.GetString()); // $ ir
CStringT<char> s3(s2);
sink(s3.GetString()); // $ ir
char* x = indirect_source<char>();
CStringT<char> s4(x);
sink(s4.GetString()); // $ ir
wchar_t* y = indirect_source<wchar_t>();
CStringT<wchar_t> s5(y);
sink(s5.GetString()); // $ ir
CStringT<char> s6(x, nullptr);
sink(s6.GetString()); // $ ir
CStringT<wchar_t> s7(y, nullptr);
sink(s7.GetString()); // $ ir
unsigned char* ucs = indirect_source<unsigned char>();
CStringT<char> s8(ucs);
sink(s8.GetString()); // $ ir
char c = source<char>();
CStringT<char> s9(c);
sink(s9.GetString()); // $ ir
wchar_t wc = source<wchar_t>();
CStringT<wchar_t> s10(wc);
sink(s10.GetString()); // $ ir
sink(static_cast<CSimpleStringT<char>&>(s1)); // $ ast ir
auto bstr = s1.AllocSysString();
sink(bstr); // $ ir
CStringT<char> s11;
s11.AppendFormat("%d", source<int>());
sink(s11.GetString()); // $ ir
CStringT<char> s12;
s12.AppendFormat(indirect_source<char>());
sink(s12.GetString()); // $ ir
CStringT<char> s13;
s13.AppendFormat(source<UINT>());
sink(s13.GetString()); // $ ir
CStringT<char> s14;
s14.AppendFormat(42, source<char>());
sink(s14.GetString()); // $ ir
CStringT<char> s15;
s15.AppendFormat(42, indirect_source<char>());
sink(s15.GetString()); // $ ir
CStringT<char> s16;
s16.AppendFormat("%s", indirect_source<char>());
CStringT<char> s17;
s17.Insert(0, x);
sink(s17.GetString()); // $ ir
CStringT<char> s18;
s18.Insert(0, source<char>());
sink(s18.GetString()); // $ ir
sink(s1.Left(42).GetString()); // $ ir
CStringT<char> s20;
s20.LoadString(source<UINT>());
sink(s20.GetString()); // $ ir
sink(s1.MakeLower().GetString()); // $ ir
sink(s1.MakeReverse().GetString()); // $ ir
sink(s1.MakeUpper().GetString()); // $ ir
sink(s1.Mid(0, 42).GetString()); // $ ir
CStringT<char> s21;
s21.Replace("abc", x);
sink(s21.GetString()); // $ ir
CStringT<char> s22;
s22.Replace('\n', source<char>());
sink(s22.GetString()); // $ ir
sink(s2.Right(42).GetString()); // $ ir
BSTR bstr2;
s1.SetSysString(&bstr2);
sink(bstr2); // $ ast ir
sink(s1.SpanExcluding("abc").GetString()); // $ ir
sink(s1.SpanIncluding("abc").GetString()); // $ ir
int start = 0;
sink(s1.Tokenize("abc", start).GetString()); // $ ir
sink(s1.Trim('a').GetString()); // $ ir
sink(s1.Trim("abc").GetString()); // $ ir
sink(s1.Trim().GetString()); // $ ir
sink(s1.TrimLeft('a').GetString()); // $ ir
sink(s1.TrimLeft("abc").GetString()); // $ ir
sink(s1.TrimLeft().GetString()); // $ ir
sink(s1.TrimRight('a').GetString()); // $ ir
sink(s1.TrimRight("abc").GetString()); // $ ir
sink(s1.TrimRight().GetString()); // $ ir
}
struct CStringData {
void* data() throw();
};
void test_CStringData() {
CStringData d = source<CStringData>();
sink(d.data()); // $ ir
}
template<typename TCharType>
struct CStrBufT {
typedef CSimpleStringT<TCharType> StringType;
using PCXSTR = typename StringType::PCXSTR;
using PXSTR = typename StringType::PXSTR;
CStrBufT(StringType& str, int nMinLength, DWORD dwFlags);
CStrBufT(StringType& str);
operator PCXSTR() const throw();
operator PXSTR() throw();
};
void test_CStrBufT() {
CStringT<char> s = source<CStringT<char>>();
CStrBufT<char> b(s, 42, 0);
sink(static_cast<CStrBufT<char>::PCXSTR>(b)); // $ ir
sink(static_cast<CStrBufT<char>::PXSTR>(b)); // $ ir
}
}
namespace Microsoft {
namespace WRL {
template <typename T>
class ComPtr;
struct GUID;
typedef GUID IID;
typedef IID *REFIID;
class IUnknown;
class WeakRef;
namespace Details {
template <typename T>
class ComPtrRef {
public:
using InterfaceType = T;
ComPtrRef(T*);
InterfaceType* const * GetAddressOf() const;
InterfaceType** ReleaseAndGetAddressOf();
operator InterfaceType**();
operator T*();
operator void**() const;
InterfaceType* operator *();
};
}
template <typename T>
class ComPtr
{
public:
using InterfaceType = T;
ComPtr();
ComPtr(const ComPtr &);
ComPtr(ComPtr &&);
template <typename U>
ComPtr(U *);
~ComPtr();
template <typename U>
HRESULT As(ComPtr<U> *p) const;
HRESULT AsWeak(WeakRef *);
void Attach(InterfaceType *);
HRESULT CopyTo(InterfaceType **);
HRESULT CopyTo(REFIID, void **) const;
template <typename U>
HRESULT CopyTo(U **) const;
T *Detach();
T *Get() const;
T *const *GetAddressOf() const;
T **GetAddressOf();
T **ReleaseAndGetAddressOf();
unsigned long Reset();
void Swap(ComPtr &&r);
void Swap(ComPtr &r);
Details::ComPtrRef<ComPtr<T>> operator&();
const Details::ComPtrRef<const ComPtr<T>> operator&() const;
InterfaceType* operator->() const; // return type simplified from Microsoft::WRL::Details::RemoveIUnknown<InterfaceType>*
ComPtr& operator=(T *);
template <typename U>
ComPtr& operator=(U *);
ComPtr& operator=(const ComPtr &);
template<class U>
ComPtr& operator=(const ComPtr<U>&);
ComPtr& operator=(ComPtr &&);
template<class U>
ComPtr& operator=(ComPtr<U>&&);
};
}
}
namespace std {
template<class T> T&& move(T& t) noexcept; // simplified signature
}
void test_constructor()
{
Microsoft::WRL::ComPtr<int> p0;
sink(*p0.Get()); // clean
int x = source<int>();
Microsoft::WRL::ComPtr<int> p1(new int(x));
sink(*p1.Get()); // $ ir MISSING: ast
sink(*p1.Detach()); // $ ir MISSING: ast
Microsoft::WRL::ComPtr<int> p2(p1);
sink(*p2.Get()); // $ ir MISSING: ast
Microsoft::WRL::ComPtr<int> p3(std::move(p1));
sink(*p3.Get()); // $ ir MISSING: ast
}
void test_As()
{
int x = source<int>();
Microsoft::WRL::ComPtr<int> p1(new int(x));
Microsoft::WRL::ComPtr<int>* p2;
p1.As(p2);
sink(*p2->Get()); // $ ir MISSING: ast
}
void test_CopyTo()
{
int x = source<int>();
Microsoft::WRL::ComPtr<int> p1(new int(x));
int *raw = nullptr;
p1.CopyTo(&raw);
sink(*raw); // $ ir MISSING: ast
Microsoft::WRL::ComPtr<int> p2;
p1.CopyTo(nullptr, (void**)&raw);
sink(*raw); // $ ir MISSING: ast
Microsoft::WRL::ComPtr<int> p3(new int(x));
int* raw2 = nullptr;
p3.CopyTo<int>(&raw2);
sink(*raw2); // $ ir MISSING: ast
}
void test_Swap()
{
int x = source<int>();
Microsoft::WRL::ComPtr<int> p1(new int(x));
Microsoft::WRL::ComPtr<int> p2;
p1.Swap(p2);
sink(*p2.Get()); // $ ir MISSING: ast
sink(*p1.Get()); // $ SPURIOUS: ir
}
void test_GetAddressOf()
{
int x = source<int>();
Microsoft::WRL::ComPtr<int> p1(new int(x));
sink(**p1.GetAddressOf()); // $ ir MISSING: ast
const Microsoft::WRL::ComPtr<int> p2(new int(x));
sink(**p2.GetAddressOf()); // $ ir MISSING: ast
Microsoft::WRL::ComPtr<int> p3(new int(x));
int **pp = p3.ReleaseAndGetAddressOf();
sink(**pp); // $ ir MISSING: ast
}
struct S {
int x;
};
void test_address_of_deref_operators() {
int x = source<int>();
Microsoft::WRL::ComPtr<int> p1(new int(x));
Microsoft::WRL::Details::ComPtrRef<Microsoft::WRL::ComPtr<int>> pp = &p1;
Microsoft::WRL::ComPtr<int>* qq = *pp;
sink(*qq->Get()); // $ MISSING: ast,ir
const Microsoft::WRL::ComPtr<int> p2(new int(x));
Microsoft::WRL::Details::ComPtrRef<const Microsoft::WRL::ComPtr<int>> pp2 = &p2;
const Microsoft::WRL::ComPtr<int>* qq2 = *pp2;
sink(*qq2->Get()); // $ MISSING: ast,ir
S s;
s.x = source<int>();
Microsoft::WRL::ComPtr<S> p3(&s);
sink(p3->x); // $ MISSING: ast,ir
}
void test_assignments() {
Microsoft::WRL::ComPtr<int> p1;
p1 = new int(source<int>());
sink(*p1.Get()); // $ MISSING: ast,ir
Microsoft::WRL::ComPtr<int> p2;
p2 = new long(source<long>());
sink(*p2.Get()); // $ MISSING: ast,ir
Microsoft::WRL::ComPtr<int> p3;
p3 = p1;
sink(*p3.Get()); // $ MISSING: ast,ir
Microsoft::WRL::ComPtr<long> p4;
p4 = p1;
sink(*p4.Get()); // $ MISSING: ast,ir
Microsoft::WRL::ComPtr<int> p5;
p5 = std::move(p1);
sink(*p5.Get()); // $ MISSING: ast,ir
Microsoft::WRL::ComPtr<long> p6;
p6 = std::move(p1);
sink(*p6.Get()); // $ MISSING: ast,ir
}