Solved

Is there a limit to the length of a document title in MFC?

Posted on 2014-10-28
6
176 Views
Last Modified: 2015-05-19
I have an MDI app in which I set the document name for each document using SetTitle() as in:

      CString sTitle(lpszTitle);
      sTitle.FormatMessage(IDS_DESIGN_TITLE_FORMAT, (CString(lpszTitle) + L":"), sConfigNameOnly);

      CDocument::SetTitle(sTitle);

sConfigNameOnly is a CString that's 20 characters long.

This all works fine until I go to the "Windows" menu that shows the names of each document and allows me to switch between them - all normal stuff.

The "Windows" menu shows the full title of the document and shows a tootip with the same string when I hover over it , as it should.

The problem is that when a document's name is greater than 61 characters long (unicode in my case) the app crashes with a memory allocation error - the usual old:  

HEAP CORRUPTION DETECTED...
CRT detected that the application wrote to memory after end of heap buffer.


Is there an undocumented maximum length that a document's title can be?  Or am I doing something wrong in this code?


The error is detected on the ::free call in CMFCPopupMenuBar::OnToolHitTest() at line #35:

INT_PTR CMFCPopupMenuBar::OnToolHitTest(CPoint point, TOOLINFO* pTI) const
{
	ASSERT_VALID(this);

	if (m_bPaletteMode)
	{
		return CMFCToolBar::OnToolHitTest(point, pTI);
	}

	int nHit = ((CMFCPopupMenuBar*)this)->HitTest(point);
	if (nHit != -1)
	{
		CMFCToolBarButton* pButton = DYNAMIC_DOWNCAST(CMFCToolBarButton, GetButton(nHit));

		if (pButton != NULL)
		{
			if (pTI != NULL)
			{
				pTI->uId = pButton->m_nID;
				pTI->hwnd = GetSafeHwnd();
				pTI->rect = pButton->Rect();
			}

			if (!pButton->OnToolHitTest(this, pTI))
			{
				nHit = pButton->m_nID;
			}
			else if (pTI != NULL && pTI->lpszText != NULL)
			{
				CString strText;

				if (pTI->lpszText != NULL)
				{
					strText = pTI->lpszText;
					::free(pTI->lpszText);
				}

				CString strDescr;
				CFrameWnd* pParent = GetParentFrame();
				if (pParent->GetSafeHwnd() != NULL && !pButton->IsKindOf (RUNTIME_CLASS(CMFCShowAllButton)))
				{
					pParent->GetMessageString(pButton->m_nID, strDescr);
				}

				CTooltipManager::SetTooltipText(pTI, m_pToolTip, AFX_TOOLTIP_TYPE_TOOLBAR, strText, strDescr);
			}
		}
	}

	return nHit;
}

Open in new window

0
Comment
Question by:allanephillips
  • 2
6 Comments
 
LVL 31

Expert Comment

by:Zoppo
ID: 40408873
Hi allanephillips,

I'm not sure what's the limit for document title is but I'm sure it's not that small coz I just tested it with a MFC application I'm working with, there I can use document title with 200 characters without problem.

I would suspect it has to do anything with tooltip handling. Do you somewhere handle tooltip messages like TTN_NEEDTEXTW or in an overridden OnToolTipText or similar?

Overriding those functionalities can be dangerous because MFC internally in some places used static CStrings to store the text to be shown in a tooltip and just pass a pointer to that string to other message handlers. If somewhere this pointer is used to write a longer string the boundary of the previously allocated string is overwritten which would lead to a similar error as you describe.

ZOPPO
0
 
LVL 33

Expert Comment

by:sarabande
ID: 40408939
looks more that you detected a bug in the mfc.

the TOOLINFO structure passed by pointer to the CMFCPopupMenuBar::OnToolHitTest has a member pointer lpszText to a string buffer of arbitrary size. if the "button" of the popup menu was "hit", the function tries to free the tool tip text pointer if it is not NULL. in debug version the debugger has allocated some extra space behind the requested buffer size and has written a end sequence to that space. when freeing the buffer the debugger looks whether the end sequence has been overwritten somehow and throws the heap error which you encountered.

to find out which function was responsible for writing beyond the buffer size, you should choose "retry" when the error occurs and then look into the stack window. the last function called is CMFCPopupMenuBar::OnToolHitTest and one of the callers up in the stack hierarchy is responsible for allocating space to the pTI->lpszText member. it is a statement like

pTI->lpszText = (LPTSTR) ::calloc((strTipText.GetLength() + 1), sizeof(TCHAR));

Open in new window

if you were successful into locating the allocation statement, you could check why the requested length is too short. in the above statement you would look for the strTipText with the debugger and check whether it contained the full title or not.

you could report the error to Microsoft but as a work around you should use a shorter title.

Sara
0
 

Accepted Solution

by:
allanephillips earned 0 total points
ID: 40409181
I did finally track down the problem.  When I searched for where the string was allocated I found that it was in an override OnMenuButtonToolHitTest() that I had created and I had called calloc() incorrectly (passed it the wrong arguments) so the buffer was too small.

Allan.
0
 
LVL 33

Expert Comment

by:sarabande
ID: 40784847
i would recommend to delete the question since the suspected limitation of the mfc title length turned out to be wrong and the final comment the author made actually cannot be looked on as a solution for the question.

i even doubt that it is a solution for the problem. mfc is a c++ framework and using malloc and calloc in an mfc event handler is a recipe for troubles such as crashes or memory leaks. i would assume that there are still issues even if the crash with the title could be avoided.

Sara
0

Featured Post

Free Tool: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

C++ Properties One feature missing from standard C++ that you will find in many other Object Oriented Programming languages is something called a Property (http://www.experts-exchange.com/Programming/Languages/CPP/A_3912-Object-Properties-in-C.ht…
Go is an acronym of golang, is a programming language developed Google in 2007. Go is a new language that is mostly in the C family, with significant input from Pascal/Modula/Oberon family. Hence Go arisen as low-level language with fast compilation…
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.

809 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question