Microsoft Office 2010 crashes juce apps due to conflicting WM_APP-based message

After launching a juce app, any application in Microsoft Office 2010 crashes the juce app at startup.

Debugger revealed that WindowMessageHelpers::messageWndProc() received a broadcastId (== WM_APP + 0x4403) message when Word or Excel was being launched. Probably the message sent from the Office application happened to have the same ID and the juce app takes lParam as a bad String pointer. Crash occurred when deleting a received String retained in ScopedPointer.

https://github.com/julianstorer/JUCE/blob/4.1.0/modules/juce_events/native/juce_win32_Messaging.cpp#L68-L72

I tried changing broadcastId and confirmed that it fixed the problem, but I'm wondering what number would be appropriate.

Wow.

Well, I wrote that broadcast code way before 2010, so it's Microsoft who are trespassing on my number, not the other way round!

Also pretty lame that their app would crash because of a message that another app sends. Presumably they'd have fixed this in later versions, as it's a bad security hole and they've been big on security since then.

jules, I think you misread the original post. If I interpret it correctly, it's the JUCE app that crashes, not Office.

Ah yes, I did mis-read that, thanks!

OK.. That's trickier then, but definitely something I should look at. Will figure something out. Unfortunately it probably means breaking backwards compatibility when broadcasting between apps built with different versions of juce, but I guess that's not really what people would use this for.

Hmm.. I don't have MS office to try, but can't see how it could crash at that point?

It seems to me that it should arrive at the WM_COPYDATA callback in juce_win32_Messaging.cpp, line 83, but even if the block of data that it's parsing is garbage, there's no way it could have a buffer overrun or anything.

Worst case that I can see would be a mangled string, but that's OK.. Is it definitely a crash and not just an assertion about some illegal unicode characters?

First look at the table here:

https://msdn.microsoft.com/en-us/library/windows/desktop/ms644930%28v=vs.85%29.aspx

If you look at the value of specialId and broadcastId, it works out to 0xC400 and 0xC403. This range is reserved for String messages for use by applications:

Message numbers in the fourth range (0xC000 through 0xFFFF) are defined at run time when an application calls the RegisterWindowMessage function to retrieve a message number for a string. All applications that register the same string can use the associated message number for exchanging messages. The actual message number, however, is not a constant and cannot be assumed to be the same between different sessions.

This means that applications will get these ideas by calling the RegisterWindowMessage function, and then they can send or broadcast those message accross applications. Excel and Word are doing this correctly, the call to RegisterWindowMessage() with whatever name they are using just happens to return 0xC403.

The solution will be to use the correct range for messages which are private to a given window class, which would be WM_USER through 0x7FFF: Integer messages for use by private window classes. I'm guessing the next range would also work.

Message numbers in the second range (WM_USER through 0x7FFF) can be defined and used by an application to send messages within a private window class. These values cannot be used to define messages that are meaningful throughout an application because some predefined window classes already define values in this range. For example, predefined control classes such as BUTTON, EDIT, LISTBOX, and COMBOBOX may use these values. Messages in this range should not be sent to other applications unless the applications have been designed to exchange messages and to attach the same meaning to the message numbers.

I think you can fix this issue without breaking backwards compatibility, as JUCE is sending WM_COPYDATA accross different apps, not broadcastId. Change the message value used internally for posting the message on the queue again, at:

  •  https://github.com/julianstorer/JUCE/blob/4.1.0/modules/juce_events/native/juce_win32_Messaging.cpp#L66
  • https://github.com/julianstorer/JUCE/blob/4.1.0/modules/juce_events/native/juce_win32_Messaging.cpp#L86

In the other places, for backwards compatibility I think you'll have to keep the old value.

--
Roeland

Ah, I see.. Righto, will sort something out. Yes, shouldn't cause any problems with backwards-compatibility.

Nice catch!

Thank you for the thoughts, everyone! I'm happy that the solution is getting clear.

Just in case, I'm sharing the easiest way to reproduce this, tested with v4.1.0:

  1. Launch JuceDemo
  2. Launch Microsoft Word 2010
  3. JuceDemo crashes