I have this string that I would like to add to a buffer using sprintf
https://objects.githubusercontent.com/github-production-release-asset-2e65be/21611723/f7cfd480-a7ea-11ea-852c-52df94ee4644?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIWNJYAX4CSVEH53A/20220728/us-east-1/s3/aws4_request&X-Amz-Date=20220728T121916Z&X-Amz-Expires=300&X-Amz-Signature=fb5d8ebe7ec4f63d462d76f059a22402ec4e9931e1b9278a739dbc0c617aedbb&X-Amz-SignedHeaders=host&actor_id=0&key_id=0&repo_id=21611723&response-content-disposition=attachment; filename=Quasar.v1.4.0.zip&response-content-type=application/octet-stream
like so i am using
FILE *p;
char url[] = "https://objects.githubusercontent.com/github-production-release-asset-2e65be/21611723/f7cfd480-a7ea-11ea-852c-52df94ee4644?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIWNJYAX4CSVEH53A/20220728/us-east-1/s3/aws4_request&X-Amz-Date=20220728T121916Z&X-Amz-Expires=300&X-Amz-Signature=fb5d8ebe7ec4f63d462d76f059a22402ec4e9931e1b9278a739dbc0c617aedbb&X-Amz-SignedHeaders=host&actor_id=0&key_id=0&repo_id=21611723&response-content-disposition=attachment; filename=Quasar.v1.4.0.zip&response-content-type=application/octet-stream";
sprintf(request, "%s %s %s", "GET", url, "HTTP/1.1");
p = fopen("out.txt" , "w");
fprintf(p , request);
fclose(p);
this results in a malformed string from out.txt
GET https://objects.githubusercontent.com/github-production-release-asset-2e65be/21611723/f7cfd480-a7ea-11ea-852c-52df94ee4644?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIWNJYAX4CSVEH53A0.000000202207280.000000us-east-10.000000s30.000000aws4_request&X-Amz-Date=20220728T121916Z&X-Amz-Expires=300&X-Amz-Signature=fb5d8ebe7ec4f63d462d76f059a22402ec4e9931e1b9278a739dbc0c617aedbb&X-Amz-SignedHeaders=host&actor_id=0&key_id=0&repo_id=21611723&response-content-disposition=attachment; 0.000000ilename=Quasar.v1.4.0.zip&response-content-type=application0.000000octet-stream HTTP/1.1
In out.txt
there is a space gap ; filename
-> ; 0.000000ilename
what workaround do I have to copy the url to the buffer, is there a way to escape strings like f
with out looping over them and decoding from url to ascii again
I outputting the request buffer to a text file just to inspect the output because the terminal does not show the problem properly
CodePudding user response:
The solution is very simple:
fprintf(p , "%s", request);
Basically, never use the string you want to output as a format. Use proper format to display string
CodePudding user response:
Since request
is the result that you want to send, don't use it as a formatting string. Use the function designed to send strings as they are, fputs
:
fputs(request, p);
If that doesn't resolve all issues, I suspect that request
is not large enough to hold the string you sprintf
into it. Use snprintf
to confirm. If request
is an automatic variable, just compare with sizeof request
:
int len = snprintf(request, sizeof request, "%s %s %s", "GET", url, "HTTP/1.1");
if((unsigned) len >= sizeof request || len < 0) {
printf("%d >= %zu or < 0\n", len, sizeof request);
exit(1);
}
CodePudding user response:
Your problem is related to escaping the %
character, you should create a function with a loop that goes over the characters of the buffer and checks if any of them is %
in this case it should add %
then add the original %
to escape that character then continue until you finish all the buffer
void esc(char * old, char * new)
{
int old_size = strlen(old), i=0,j=0;
while ( i < old_size)
{
if (old[i] == '%')
{
new[j] = '%';
j ;
new[j] = old[i];
}
new[j] = old[i];
i ,j ;
}
new[j] = '\0';
}
int main()
{
char new[1024];
char buffer[4096];
char link[] = "https://objects.githubusercontent.com/github-production-release-asset-2e65be/21611723/f7cfd480-a7ea-11ea-852c-52df94ee4644?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIWNJYAX4CSVEH53A/20220728/us-east-1/s3/aws4_request&X-Amz-Date=20220728T132853Z&X-Amz-Expires=300&X-Amz-Signature=8de49cce44acb53aff3a2d284cd402f4b1a7cd6fa9335ec7c8be5b3a5d96d24c&X-Amz-SignedHeaders=host&actor_id=0&key_id=0&repo_id=21611723&response-content-disposition=attachment; filename=Quasar.v1.4.0.zip&response-content-type=application/octet-stream";
esc(link , new);
sprintf(buffer , "%s %s HTTP/1.1", "GET", new);
printf("%s\n", buffer);
return 0;
}
final result looks like this
GET https://objects.githubusercontent.com/github-production-release-asset-2e65be/21611723/f7cfd480-a7ea-11ea-852c-52df94ee4644?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIWNJYAX4CSVEH53A%/20220728%/us-east-1%/s3%/aws4_request&X-Amz-Date=20220728T132853Z&X-Amz-Expires=300&X-Amz-Signature=8de49cce44acb53aff3a2d284cd402f4b1a7cd6fa9335ec7c8be5b3a5d96d24c&X-Amz-SignedHeaders=host&actor_id=0&key_id=0&repo_id=21611723&response-content-disposition=attachment%;% filename%=Quasar.v1.4.0.zip&response-content-type=application%/octet-stream HTTP/1.1