I could use a second set of eyes on curl_easy_escape

Hi everyone,

I have a std::string called fileUrl that’s set to something like:

https://upcdn.io/W142hWD/raw/uploads/2022/10/28/file-4B1P.wav

I’d like to POST that URL to a webservice using libcurl in C++. But in order to do that, I need to escape the special characters. I tried this:

      DEBUG("fileUrl=");
      DEBUG(fileUrl.c_str());

      std::string escaped_fileUrl = curl_easy_escape(NULL, fileUrl.c_str(), 0);

      DEBUG("escaped_fileUrl=");
      DEBUG(escaped_fileUrl.c_str());

The output of the debug statements is:

[5.782 debug src/AudioPoop/AudioPoop.hpp:123 WriteCallback] fileUrl=
[5.782 debug src/AudioPoop/AudioPoop.hpp:124 WriteCallback] https://upcdn.io/W142hWD/raw/uploads/2022/10/28/file-4B1P.wav
[5.782 debug src/AudioPoop/AudioPoop.hpp:129 WriteCallback] escaped_fileUrl=
[5.782 debug src/AudioPoop/AudioPoop.hpp:130 WriteCallback] https0X0P+00.0000000.000000upcdn.io0.000000W142hWD0.000000raw0.000000uploads0.00000020220.000000100.000000280.000000file-4B1P.wav

I could be wrong, but that doesn’t look like it was escaped properly. Any ideas?

Thanks!

Is there some locale thing happening on fileUrl? Just curious why the cut & paste of debug statements shows up with formatting (italics and color) on the URL. Stab in the dark, I dunno. What do you get if you set fileUrl to a test string and try it?

“The forums will try to automatically detect what language you are typing and style your code accordingly. This might be nice for sharing code, but tends to produce strange results when sharing other preformatted text. To avoid the automatic styling, declare your code to be “raw text” by typing text after the first 3 back ticks.” (Link)

'''text
The text to be quoted
'''
1 Like

R u sure that it’s ok to pass null as the first argument? The docs don’t mention that.

The man-page includes:

Since 7.82.0, the curl parameter is ignored. Prior to that there was per-handle character conversion support for some very old operating systems such as TPF, but it was otherwise ignored.

I believe this has to do with how you call the DEBUG-macro; it is supposed to be called somewhat like printf, i.e. like DEBUG(format-str, ...).

Running the following snippet as part of loading a dummy module produces essentially expected results.

    std::string s{"https://upcdn.io/W142hWD/raw/uploads/2022/10/28/file-4B1P.wav"};
    std::string res{curl_easy_escape(NULL, s.c_str(), 0)};
    std::string res2{curl_easy_unescape(NULL, res.c_str(), 0, NULL)};

    std::cout << s << std::endl;
    std::cout << res << std::endl;
    std::cout << res2 << std::endl;

    DEBUG(s.c_str());
    DEBUG(res.c_str());
    DEBUG(res2.c_str());

    DEBUG("%s", s.c_str());
    DEBUG("%s", res.c_str());
    DEBUG("%s", res2.c_str());

Compiling and running this on Arch Linux produces the following to appear in the Rack log. The plain iostream printouts gives the correct result, as does the second set of DEBUG-printouts. In the first set of DEBUG-printouts, where there is no format string, the actual string to print is interpreted as being the format string, which presumably garbles things. I did not dig deeper into what it actually does (edit: but as % is significant in the format string, presumably parts of the encoded string gets interpreted as being formatting specifications, like %3A and %2F specifying different floating point formats).

https://upcdn.io/W142hWD/raw/uploads/2022/10/28/file-4B1P.wav
https%3A%2F%2Fupcdn.io%2FW142hWD%2Fraw%2Fuploads%2F2022%2F10%2F28%2Ffile-4B1P.wav
https://upcdn.io/W142hWD/raw/uploads/2022/10/28/file-4B1P.wav
[0.287 debug src/HelloWorld.cpp:46 Test] https://upcdn.io/W142hWD/raw/uploads/2022/10/28/file-4B1P.wav
[0.287 debug src/HelloWorld.cpp:47 Test] https0X0.07F958226508P-10220.0000000.000000upcdn.io0.000000W142hWD0.000000raw0.000000uploads0.00000020220.000000100.000000280.000000file-4B1P.wav
[0.287 debug src/HelloWorld.cpp:48 Test] https://upcdn.io/W142hWD/raw/uploads/2022/10/28/file-4B1P.wav
[0.287 debug src/HelloWorld.cpp:50 Test] https://upcdn.io/W142hWD/raw/uploads/2022/10/28/file-4B1P.wav
[0.287 debug src/HelloWorld.cpp:51 Test] https%3A%2F%2Fupcdn.io%2FW142hWD%2Fraw%2Fuploads%2F2022%2F10%2F28%2Ffile-4B1P.wav
[0.287 debug src/HelloWorld.cpp:52 Test] https://upcdn.io/W142hWD/raw/uploads/2022/10/28/file-4B1P.wav
4 Likes

Interesting. I never thought about the case where the string looks like a format string with substitutions. Of courses printf with a plain string works fine. In any case, looks like you found the answer.

oh WOW! Thanks so much for helping troubleshoot! I owe you a beer. Or perhaps a new feature that you need on one of my modules. :slight_smile:

Ha, ha, no problem, happy to help!

I’m still somewhat new to this whole VCV Rack thing, so I don’t yet have many requests; I’m busy just digging around testing all the stuff, trying to figure out how things work. But I’ll keep your offer as a rain check! :smile: