electron/rcedit

Unable to set icon on an exe which doesn't have an icon currently set

thomasmfields opened this issue · 10 comments

Hi there,

I can't seem to be able to change the icon on an exe that is using the Windows default exe icon.

To repro the issue:

  1. Open the rcedit solution file
  2. Go to Project Properties->C/C++->Code Generation->Runtime Library and change it to "Multi threaded Debug /Mtd"
  3. Build from source
  4. Set debugging arguments to:

C:\some_path_to_exe\testexe.exe --set-icon "C:\some_path_to_icon\icon.ico"

Note how you get:

Debug Assertion Failed!

Program: C:\Users\gbfieldst\Downloads\rcedit-master\Default\rcedit.exe
File: C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\xtree
Line: 238

Expression: map/set iterator not dereferencable

Callstack:

rcedit.exe!std::_Debug_message(const wchar_t * message, const wchar_t * file, unsigned int line) Line 17 C++
rcedit.exe!std::_Tree_const_iterator<std::_Tree_val<std::_Tree_simple_types<std::pair<unsigned short const ,rescle::ResourceUpdater::IconResInfo> > > >::operator*() Line 239 C++
[Inline Frame] rcedit.exe!std::_Tree_iterator<std::_Tree_val<std::_Tree_simple_types<std::pair<unsigned short const ,rescle::ResourceUpdater::IconResInfo> > > >::operator*() C++
[Inline Frame] rcedit.exe!std::_Tree_iterator<std::_Tree_val<std::_Tree_simple_types<std::pair<unsigned short const ,rescle::ResourceUpdater::IconResInfo> > > >::operator->() C++
rcedit.exe!rescle::ResourceUpdater::SetIcon(const wchar_t * path) Line 640 C++
rcedit.exe!wmain(int argc, const wchar_t * * argv) Line 83 C++

This is because ResourceUpdater::SetIcon(const WCHAR* path) does:

auto& langId = iconBundleMap.begin()->first;

but the map is empty!

The executable I used is attached. It's 01_vertex_program.exe from the NVIDIA Cg toolkit install.
01_vertex_program.zip

Any ideas how this might be fixed?

Regards,
Tom

I think this is the same as #56, although with more C++ debug info.

Not sure. The copy of rcedit I have was downloaded on 9th Sept, which predates the commit mentioned in #56

Could you make sure it's reproducible with the latest rcedit?

With the latest rcedit I get:

Unable to set icon.

So that's good. So rcedit can only replace icons rather than add them? Is that correct?

That's my understanding.

OK. So I'm now hitting #56 which used to work prior to updating to latest.

The fix for #56 has now caused this issue again.

I tried your example with this artifact - it worked.

Nevertheless there is a bug: accessing the key of the 'first' element of an empty map should be considered.

I just tried these changes:

diff --git a/src/rescle.cc b/src/rescle.cc
index 8ca6f60..a0779d2 100644
--- a/src/rescle.cc
+++ b/src/rescle.cc
@@ -606,12 +606,18 @@ bool ResourceUpdater::SetIcon(const WCHAR* path, const LANGID& langId,
 }

 bool ResourceUpdater::SetIcon(const WCHAR* path, const LANGID& langId) {
-  UINT iconBundle = iconBundleMap_[langId].iconBundles.begin()->first;
+  UINT iconBundle;
+  if (!iconBundleMap_[langId].iconBundles.empty()) {
+    iconBundle = iconBundleMap_[langId].iconBundles.begin()->first;
+  }
   return SetIcon(path, langId, iconBundle);
 }

 bool ResourceUpdater::SetIcon(const WCHAR* path) {
-  LANGID langId = iconBundleMap_.begin()->first;
+  LANGID langId;
+  if (!iconBundleMap_.empty()) {
+       langId = iconBundleMap_.begin()->first;
+  }
   return SetIcon(path, langId);
 }

They seem to work - I did not get Errors for your testcase (I did not test anything other.)

@thomasmfields Can you confirm that this patch works?
Given a positive response I can prepare a Pull Request.

Looks good to me.