Search

ParaSoft

HOME
PRODUCTS
SUPPORT
ABOUT
WHAT'S NEW
EVENTS


Insure++

Quick facts

Add-on Modules:
   -INUSE
   -TCA

Comparisons

Technical Papers

Support & Manuals

FAQs

Recent Reviews

User Testimonials

Press Releases


Insure tool to debug c++





Insure++ Reference - BAD_FORMAT



BAD_FORMAT

Mismatch in format specification

This error is generated when a call to one of the printf or scanf routines contains a mismatch between a parameter type and the corresponding format specifier or the format string is nonsensical.

Insure++ distinguishes several types of mismatch which have different levels of severity as follows:

sign
Types differ only by sign, e.g., int vs. unsigned int.
compatible
Fundamental types are different but they happen to have
the same representation on the particular hardware in use,
e.g., int vs. long on machines where both are 32-bits,
or int * vs. long where both are 32-bits.
incompatible
Fundamental types are different, e.g. int vs. double.
other
A problem other than an argument type mismatch is detected,
such as passing the wrong number of arguments.

Error messages are classified according to this scheme and can be selectively enabled or disabled as described in the "Repair" section.

Problem #1

An example of format type mismatch occurs when the format specifiers passed to one of the printf routines do not correspond to the data, as shown below.


	1: 	/*
	2:	 * File: badform1.c
	3:	 */
	4:	main()
	5:	{
	6:		double f = 1.23;
	7:		int i = 99;
	8:
	9:		printf("%d %f\n\", f, i); bug
	10:	}

This type of mismatch is detected during compilation.

Diagnosis (during compilation)


1.	[badform1.c:9] **BAD_FORMAT(incompatible)**
2.		Wrong type passed to printf (argument 2).
		Expected int, found double.
	>>		printf("%d %f\n", f, i);

	[badform1.c:9] **BAD_FORMAT(incompatible)**
		Wrong type passed to printf (argument 3).
		Expected double, found int.
	>>		printf("%d %f\n", f, i);


  1. Source lines at which problems were detected.
  2. Description of the problem and the arguments that are incorrect.

Problem #2

A more dangerous problem occurs when the types passed as arguments to one of the scanf functions are incorrect. In the following code, for example, the call to scanf tries to read a double precision value, indicated by the "%lf" format, into a single precision value. This will overwrite memory.


	1: 	/*
	2:	 * File: badform2.c
	3:	 */
	4:	main()
	5:	{
	6:		int a;
	7:		float f;
	8:
	9:		scanf("%lf\', &f); bug
	10:	}

This problem is again diagnosed at compile time along with the WRITE_OVERFLOW, which is not shown below).

Diagnosis (during compilation)


1.	[badform2.c:8] **BAD_FORMAT(incompatible)**
2.		Wrong type passed to scanf (argument 2).
		Expected double *, found float *.
	>>		scanf("%lf\n", &f);


  1. Source lines at which problems were detected.
  2. Description of the problem and the arguments that are incorrect.

Problem #3

A third type of problem is caused when the format string being used is a variable rather than an explicit string. The following code contains an error handler that attempts to print out a message containing a filename and line number. In line 18


	1: 	/*
	2:	 * File: badform3.c
	3:	 */
	4:	char *file;
	5:	int line;
	6:
	7:	error(format)
	8:		char *format;
	9:	{
	10:		printf(format, file, line); bug
	11:	}
	12:
	13: 	main()
	14:	{
	15:		file = "foo.c";
	16:		line = 3;
	17:
	18:		error("Line %d, file %s\n");
	19:	}

of the calling routine, however, the arguments are reversed.

Diagnosis (at runtime)


	[badform3.c:10] **BAD_FORMAT(incompatible)**
1.	>> 		printf(format, file, line);

2.		Format string is inconsistent:
			Wrong type passed to printf (argument 3).
		Expected pointer, found int.
3.		Format string: "Line %d, file %s\n"

		Stack trace where the error occurred:
4.			error() badform3.c, 10
               		 main() badform3.c, 18


  1. Source line at which the problem was detected.
  2. Description of the problem and the argument that is in error.
  3. Explanation of the error and the format string that caused it.
  4. Stack trace showing the function call sequence leading to the error.

The error diagnosed in this message is in the "incompatible" category, because any attempt to print a string by passing an integer variable will result in garbage. Note that with some compilers, this program may cause a core dump because of this error, while others will merely produce incorrect output.

There is, however, a second potential error in this code in the same line.

Because the arguments are in the wrong order in line 7, an attempt will be made to print a pointer variable as an integer. This error is in the "compatible" class, since a pointer and an integer are both the same size in memory. Since "compatible" BAD_FORMAT errors are suppressed by default, you will not see it. (These errors are suppressed because they will cause unexpected rather than incorrect behavior.)

If you enabled these errors, you would see a second problem report from this code.

Bend
If you run Insure++ on an architecture where pointers and integers are not the same length, then this second error would also be in the "incompatible" class and would be displayed by default.

Repair

Most of these problems are simple to correct based on the information given. Normally, the correction is one or more of the following

  • Change the format specifier used in the format string.
  • Change the type of the variable involved.
  • Add a suitable typecast.

For example, problem #1 can be corrected by simply changing the incorrect line of code as follows

	badform1.c, line 9:printf("%d %f\n", i, f);

The other problems can be similarly corrected.

If your application generates error messages that you wish to ignore, you can add the option

	insure++.suppress BAD_FORMAT

to the .psrc file.

This directive suppresses all BAD_FORMAT messages. If you wish to be more selective and suppress only a certain type of error, you can use the syntax

	insure++.suppress BAD_FORMAT(class1, class2, ...)

where the arguments are one or more of the identifiers for the various categories of error described in BAD_FORMAT.

Similarly, you can enable suppressed types with an unsuppress command. The problem with the pointer and integer that was not shown in the current example could be displayed by adding the option

	insure++.unsuppress BAD_FORMAT(compatible)

to your .psrc file.


<- BAD_DECL -> BAD_INTERFACE
Tools to debug c++ and java
(888) 305-0041 info@parasoft.com Copyright © 1996-2001 ParaSoft