2014-02-14 128 views
0

所以我一直有生產中的問題,似乎通過服務包升級公開。它似乎是某種ado _ConnectionPtr對象的Execute方法中的某種緩衝區溢出。以下代碼是什麼產生緩衝區溢出:vc6 ado執行緩衝區溢出

char szStatement[600]; 
sprintf(szStatement, "UPDATE ROUTING_MASTER SET CNTNR_WGT_EST = %g WHERE CNTNR_ID = '%s'", 
         spLineItem->CntnrItemsWeight, (LPCTSTR) spLineItem->ContainerID); 

m_spCN->Execute(szStatement,&var,adCmdText); 

它踐踏我的成員變量(_bstr_t)和應用程序試圖訪問它拋出異常的踐踏成員變量的下一個時間的一個執行方法之後。我可以告訴它的被踐踏,因爲我有我的成員變量在監視窗口和執行方法完成立刻之後我看到成員變量發生了變化(m_bstrDate):

enter image description here

VAR在頭文件中聲明如:

variant_t var; 
BOOL m_bUseStorePutCntnr; 
_bstr_t m_bstrDate, m_bstrTime; 

這樣看來,分配給&變種是什麼做的,因爲如果我把它更改爲以下不踐踏我的成員變量:

m_spCN->Execute(szStatement, NULL, adCmdText); 

我不確定這是否與服務包有關,因爲我在開發環境中看到了這一點,並且Visual Studio在下次必須訪問該成員變量時纔會繼續前進。

任何想法爲什麼這會導致緩衝區溢出?

+0

嗯,你正在使用'sprintf',它不檢查緩衝區大小,緩衝區溢出是否會導致這種情況? – sashoalm

+0

它似乎不是當我調試它的szStatement的大小看起來不錯。看起來是正確的空終止和小於600字節(szStatement的大小)。我還在上面添加了szStatement的聲明。 –

回答

0

我沒有帶有ADO環境設置的Visual C/C++ v6.0,因此我無法驗證以下任何內容。

但很明顯,用第二個參數Execute方法傳遞的保留內存塊的地址不夠大。

我無法在MSDN中找到類_ConnectionPtr,也沒有關於此類的方法Execute。但我發現頁面ADO interface _ConnectionPtr。根據該頁面的原型方法Execute是:

_RecordsetPtr Connection :: Execute (_bstr_t CommandText, VARIANT * RecordsAffected, long Options) 

因此,第二個參數是一個指向結構VARIANT

但是,您已將成員變量var定義爲類variant_t的對象,該對象封裝了VARIANT結構。

我100%該結構VARIANT的大小是類variant_t的尺寸不同。

您應該能夠通過插入到你的代碼來驗證:

TRACE("Size of VARIANT is %u and size of variant_t is %u\n",sizeof(VARIANT),sizeof(variant_t)); 

我的結論:

您傳遞了錯誤的對象方法Execute

您的應用程序應該由VARIANT也許明確了結構的所有字節與

memset(&var,0,sizeof(var)); 

在你的頭文件variant_t更換工作調用方法Execute之前,雖然我很肯定這是不是真的需要。

如果你想另外使用類variant_t,你必須定義仍然還VARIANT結構並將其連接到variant_t對象。

這將意味着你需要在頭文件:

VARIANT var; 
variant_t RecordsAffected; 

和源文件中:

memset(&var,0,sizeof(var)); // Most likely not really needed. 
m_spCN->Execute(szStatement,&var,adCmdText); 
RecordsAffected.Attach(&var); 

請讓我知道,如果我的代碼片段,我無法測試犯過錯誤以及我的答案中的任何其他錯誤信息。