Solved

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

Posted on 2014-10-28
6
161 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 30

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 32

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 32

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

Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

Join & Write a Comment

Written by John Humphreys C++ Threading and the POSIX Library This article will cover the basic information that you need to know in order to make use of the POSIX threading library available for C and C++ on UNIX and most Linux systems.   [s…
Introduction This article is the first in a series of articles about the C/C++ Visual Studio Express debugger.  It provides a quick start guide in using the debugger. Part 2 focuses on additional topics in breakpoints.  Lastly, Part 3 focuses on th…
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.

747 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

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now