Skip to content

Commit 4b60767

Browse files
committed
Fix memory errors caused by invalid pointer access in Release() and broken ComPtr smart pointer implementation.
1 parent cdaa11b commit 4b60767

File tree

9 files changed

+34
-41
lines changed

9 files changed

+34
-41
lines changed

ComPtr.h

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ class ComPtr {
3333
ComPtr(void): p_(NULL) {
3434
}
3535

36-
ComPtr(T* p): p_(p) {
37-
if(p_)
36+
ComPtr(T* p, bool ref = true): p_(p) {
37+
if(p_ && ref)
3838
p_->AddRef();
3939
}
4040

@@ -81,12 +81,17 @@ class ComPtr {
8181
return p_ < p;
8282
}
8383

84+
ComPtr& operator = (const ComPtr& other) {
85+
return operator = (other.p_);
86+
}
87+
8488
ComPtr& operator = (T* p) {
85-
if(p_)
86-
p_->Release();
89+
T* old = p_;
8790
p_ = p;
8891
if(p_)
8992
p_->AddRef();
93+
if (old)
94+
old->Release();
9095
return *this;
9196
}
9297

DisplayAttributeInfo.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,10 @@ STDMETHODIMP_(ULONG) DisplayAttributeInfo::AddRef(void) {
6262

6363
STDMETHODIMP_(ULONG) DisplayAttributeInfo::Release(void) {
6464
assert(refCount_ > 0);
65-
--refCount_;
65+
const ULONG newCount = --refCount_;
6666
if(0 == refCount_)
6767
delete this;
68-
return refCount_;
68+
return newCount;
6969
}
7070

7171
// ITfDisplayAttributeInfo

DisplayAttributeInfoEnum.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,10 @@ STDMETHODIMP_(ULONG) DisplayAttributeInfoEnum::AddRef(void) {
6262

6363
STDMETHODIMP_(ULONG) DisplayAttributeInfoEnum::Release(void) {
6464
assert(refCount_ > 0);
65-
--refCount_;
66-
if(0 == refCount_)
65+
const ULONG newCount = --refCount_;
66+
if (0 == refCount_)
6767
delete this;
68-
return refCount_;
68+
return newCount;
6969
}
7070

7171

DisplayAttributeProvider.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,10 @@ STDMETHODIMP_(ULONG) DisplayAttributeProvider::AddRef(void) {
6161

6262
STDMETHODIMP_(ULONG) DisplayAttributeProvider::Release(void) {
6363
assert(refCount_ > 0);
64-
--refCount_;
65-
if(0 == refCount_)
64+
const ULONG newCount = --refCount_;
65+
if (0 == refCount_)
6666
delete this;
67-
return refCount_;
67+
return newCount;
6868
}
6969

7070

EditSession.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,10 @@ STDMETHODIMP_(ULONG) EditSession::AddRef(void) {
6767

6868
STDMETHODIMP_(ULONG) EditSession::Release(void) {
6969
assert(refCount_ > 0);
70-
--refCount_;
71-
if(0 == refCount_)
70+
const ULONG newCount = --refCount_;
71+
if (0 == refCount_)
7272
delete this;
73-
return refCount_;
73+
return newCount;
7474
}
7575

7676
STDMETHODIMP EditSession::DoEditSession(TfEditCookie ec) {

ImeModule.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -505,10 +505,11 @@ STDMETHODIMP_(ULONG) ImeModule::Release(void) {
505505
// The last reference is released in DllMain() when unloading.
506506
// Hence interlocked operations are enough here, I guess.
507507
assert(refCount_ > 0);
508+
const ULONG newCount = --refCount_;
508509
if(::InterlockedExchangeSubtract(&refCount_, 1) == 1) {
509510
delete this;
510511
}
511-
return refCount_;
512+
return newCount;
512513
}
513514

514515
// IClassFactory

LangBarButton.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -212,10 +212,10 @@ STDMETHODIMP_(ULONG) LangBarButton::AddRef(void) {
212212

213213
STDMETHODIMP_(ULONG) LangBarButton::Release(void) {
214214
assert(refCount_ > 0);
215-
--refCount_;
216-
if(0 == refCount_)
215+
const ULONG newCount = --refCount_;
216+
if (0 == refCount_)
217217
delete this;
218-
return refCount_;
218+
return newCount;
219219
}
220220

221221
// ITfLangBarItem

TextService.cpp

Lines changed: 8 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -68,12 +68,6 @@ TextService::~TextService(void) {
6868
}
6969
}
7070

71-
if(!langBarButtons_.empty()) {
72-
for(vector<LangBarButton*>::iterator it = langBarButtons_.begin(); it != langBarButtons_.end(); ++it) {
73-
LangBarButton* button = *it;
74-
button->Release();
75-
}
76-
}
7771
if(langBarMgr_) {
7872
langBarMgr_->UnadviseEventSink(langBarSinkCookie_);
7973
}
@@ -108,31 +102,26 @@ DWORD TextService::langBarStatus() const {
108102

109103
void TextService::addButton(LangBarButton* button) {
110104
if(button) {
111-
langBarButtons_.push_back(button);
112-
button->AddRef();
105+
langBarButtons_.emplace_back(button);
113106
if(isActivated()) {
114-
ITfLangBarItemMgr* langBarItemMgr;
107+
ComPtr<ITfLangBarItemMgr> langBarItemMgr;
115108
if(threadMgr_->QueryInterface(IID_ITfLangBarItemMgr, (void**)&langBarItemMgr) == S_OK) {
116109
langBarItemMgr->AddItem(button);
117-
langBarItemMgr->Release();
118110
}
119111
}
120112
}
121113
}
122114

123115
void TextService::removeButton(LangBarButton* button) {
124116
if(button) {
125-
vector<LangBarButton*>::iterator it;
126-
it = find(langBarButtons_.begin(), langBarButtons_.end(), button);
117+
auto it = find(langBarButtons_.begin(), langBarButtons_.end(), button);
127118
if(it != langBarButtons_.end()) {
128119
if(isActivated()) {
129-
ITfLangBarItemMgr* langBarItemMgr;
120+
ComPtr<ITfLangBarItemMgr> langBarItemMgr;
130121
if(threadMgr_->QueryInterface(IID_ITfLangBarItemMgr, (void**)&langBarItemMgr) == S_OK) {
131122
langBarItemMgr->RemoveItem(button);
132-
langBarItemMgr->Release();
133123
}
134124
}
135-
button->Release();
136125
langBarButtons_.erase(it);
137126
}
138127
}
@@ -621,13 +610,13 @@ STDMETHODIMP_(ULONG) TextService::AddRef(void) {
621610

622611
STDMETHODIMP_(ULONG) TextService::Release(void) {
623612
assert(refCount_ > 0);
624-
--refCount_;
613+
const ULONG newCount = --refCount_;
625614
if(0 == refCount_) {
626615
// ImeModule needs to do some clean up before deleting the TextService object.
627616
module_->removeTextService(this);
628617
delete this;
629618
}
630-
return refCount_;
619+
return newCount;
631620
}
632621

633622
// ITfTextInputProcessor
@@ -700,8 +689,7 @@ STDMETHODIMP TextService::Activate(ITfThreadMgr *pThreadMgr, TfClientId tfClient
700689
if(!langBarButtons_.empty()) {
701690
ComPtr<ITfLangBarItemMgr> langBarItemMgr;
702691
if(threadMgr_->QueryInterface(IID_ITfLangBarItemMgr, (void**)&langBarItemMgr) == S_OK) {
703-
for(vector<LangBarButton*>::iterator it = langBarButtons_.begin(); it != langBarButtons_.end(); ++it) {
704-
LangBarButton* button = *it;
692+
for(auto& button: langBarButtons_) {
705693
langBarItemMgr->AddItem(button);
706694
}
707695
}
@@ -729,8 +717,7 @@ STDMETHODIMP TextService::Deactivate() {
729717
if(!langBarButtons_.empty()) {
730718
ComPtr<ITfLangBarItemMgr> langBarItemMgr;
731719
if(threadMgr_->QueryInterface(IID_ITfLangBarItemMgr, (void**)&langBarItemMgr) == S_OK) {
732-
for(vector<LangBarButton*>::iterator it = langBarButtons_.begin(); it != langBarButtons_.end(); ++it) {
733-
LangBarButton* button = *it;
720+
for(auto& button: langBarButtons_) {
734721
langBarItemMgr->RemoveItem(button);
735722
}
736723
}

TextService.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,7 @@ class TextService:
305305

306306
ITfComposition* composition_; // acquired when starting composition, released when ending composition
307307
ComPtr<ITfLangBarMgr> langBarMgr_;
308-
std::vector<LangBarButton*> langBarButtons_;
308+
std::vector<ComPtr<LangBarButton>> langBarButtons_;
309309
std::vector<PreservedKey> preservedKeys_;
310310
std::vector<CompartmentMonitor> compartmentMonitors_;
311311

0 commit comments

Comments
 (0)