Home > Blockchain >  How to deal with percent symbols in string when using sprintf
How to deal with percent symbols in string when using sprintf

Time:07-29

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
  • Related