I am writing a function which prints out to as standard output, like how a regular printf function does but instade of taking indicators like %d or %s it takes {i} or {s}. The problem i have is that when the string of the format argument is too long about 23 characters, i get a segmentation fault at the line where i am calling vfprintf function.
int mr_asprintf(const char *format, ...)
{
int i;
char *newFormat = calloc(1,sizeof(char));
char integer[3] = "%d";
char str[3] = "%s";
char tmpStr[2];
va_list args;
newFormat[0] ='\0';
tmpStr[1] = '\0';
for(i=0;format[i]!='\0';i++) // convert to printf syntaxe
{
if(format[i]=='{' && format[i+2]=='}') //check if it's {x}
{
switch(format[i+1])
{
case 'i':
strcat(newFormat,integer);
i += 2;
break;
case 's':
strcat(newFormat,str);
i += 2;
break;
}
}
else
{
tmpStr[0] = format[i];
strcat(newFormat,tmpStr);
}
}
va_start(args,format);
int s = vfprintf(stdout,newFormat,args);
va_end(args);
free(newFormat);
return s;
}
Test example :
int main()
{
char *result = mr_asprintf("bce }edadacba{i}}aa}da{s}fe aeaee d{i}cefaa",55,"XXX",66);
printf("%s\n",result);
return 0;
}
Your string newFormat
is being allocated as size 1, and you are appending to it with strcat - but strcat does not do any array resizing, so newFormat
will soon begin to stomp on unallocated memory. The length of your output string will always be <= the length of the input string, so you should probably allocate a string of that size.
Finally, while this shouldn't cause a segfault in vprintf, it might cause unexpected behavior later -
for(i=0;format[i]!='\0';i++) // convert to printf syntaxe
{
if(format[i]=='{' && format[i+2]=='}') //check if it's {x}
You check if the current location is the end of the string, and then check two characters after the current location for a closing bracket, without checking if the string ended on the next space . This could lead to reads outside of the allocated memory for your array. Replacing the if statement with if(format[i]=='{' && (format[i+1]=='i' || format[i+1]=='s') && format[i+2]=='}')
would avoid the issue.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.