My understanding is that the function char *tparm(char *str, ...); just converts the given string str to an expanded parameterized version which will be fine to use with stdout outputting functions like printf or cout. But the man page mentions -
Parameterized strings should be passed through tparm to instantiate them. All terminfo strings [including the output of tparm] should be printed with tputs or putp.
So can I parse terminfo entries and use tparm() on them passing appropriate parameters and output them using stdout output functions? Also I'm doing the checks of non-tty output and ignoring these methods so I got that base covered.
Sure, you can. But some capability strings include padding and time delays, which tparm assumes will be interpreted by tputs.
For instance, the flash capability would use time-delays, which are passed along to tputs (using the syntax described in the terminfo(5) manual page).
Related
I have code like the following
flags->add_option("--name", name_, "The name.")->required();
I want to be able to pass strings like "aa$p$aa" to the --name parameter. However, this does not seem to work with CLI11, and the name gets truncated to just "aa". I need to escape the $ characters to properly read the strings. So aa\$p\$aa works fine, and I get the expected string ("aa$p$aa").
Changing the function to add_flag() does not work either.
Is there a way to be able to pass arbitrary strings to a parameter as with either function calls above?
Your operating system takes the command you type in and executes the given program, passing the parameters to it.
The interpolation, and the handling of $ characters in typed-in commands is handled by your operating system as part of executing the typed-in command. Your compiled C++ program receives the transformed arguments, as parameters. Your C++ program has no means to control what has happened before it was even executed.
In my code the following line gives me data that performs the task its meant for:
const char *key = "\xf1`\xf8\a\\\x9cT\x82z\x18\x5\xb9\xbc\x80\xca\x15";
The problem is that it gets converted at compile time according to rules that I don't fully understand. How does "\x" work in a String?
What I'd like to do is to get the same result but from a string exactly like that fed in at run time. I have tried a lot of things and looked for answers but none that match closely enough for me to be able to apply.
I understand that \x denotes a hex number. But I don't know in which form that gets 'baked out' by the compiler (gcc).
What does that ` translate into?
Does the "\a" do something similar to "\x"?
This is indeed provided by the compiler, but this part is not member of the standard library. That means that you are left with 3 ways:
dynamically write a C++ source file containing the string, and writing it on its standard output. Compile it and (providing popen is available) execute it from your main program and read its input. Pretty ugly isn't it...
use the source of an existing compiler, or directly its internal libraries. Clang is probably a good starting point because it has been designed to be modular. But it could require a good amount of work to find where that damned specific point is coded and how to use that...
just mimic what the compiler does, and write your own parser by hand. It is not that hard, and will learn you why tests are useful...
If it was not clear until here, I strongly urge you to use the third way ;-)
If you want to translate "escape" codes in strings that you get as input at run-time then you need to do it yourself, explicitly.
One way is to read the input into one string. Then copy the characters from that source string into a new destination string, one by one. If you see a backslash then you discard it, fetch the next character, and if it's an x you can use e.g. std::stoi to convert the next few characters into its corresponding integer value, and append that number to the destination string (either adding it with std::to_string, or using output string streams and the normal "output" operator <<).
The following piece of code works in C++ when running on Windows:
void* paramsList[MAX_PARAMS_NUM] = { 0 };
...some code to populate paramsList (p.s MAX_PARAMS_NUM is a constant)
vsnprintf((char*)pStr, MAXLEN, (char*)pTempFormat, (va_list)paramsList);
This code works fine on Windows, but i am trying to make it run on Linux and the program crushes because this conversion of paramsList to va_list doesn't work there.
Now the setting of this scenario is that i get a format string from a server that i don't control. The format string ('pTempFormat') is like the one used in printf of unknown number of % in it (maximum is MAX_PARAMS_NUM) and i populate the paramsList accordingly and then i use vsnprintf to create a string from the format string i got and the values populated in paramsList.(those values can be anything from integers, to hex to char * (aka strings) and any combination of them, according to the format string received from the server).
i don't know how many locations paramsList to pass to vsnprintf until i finish populating it according to the format string received from the server. So i need to somehow either pass a variable number of locations from paramsListto vsnprintf or to convert those locations into va_list (which i couldn't figure out how to do from what i read online).
I also considered using a combination of variadic templates and va_list - to somehow pass a variable number of locations from paramsListto a variadic function and to pass them on to vsnprintf. But i couldn't figure out how to pass certain locations from a given array to a variadic function either.
Update:
I use Visual Studio 2015 to compile on Windows, and GCC 4.9 on Ubuntu.
The error i am getting when trying to compile this code on Linux is: error: ISO C++ forbids casting to an array type 'va_list {aka __va_list_tag [1]}'
va_list is an unspecified type. That means it may be a void* [] or something else entirely.
That it worked by chance in some cases is just that va_list is compatible with void* [] on one particular platform for one compiler, it is by no means indication that this is legal.
The correct way to deal with this is, unfortunately, to stop using the printf family and parse the format string yourself, there is no standard functionality to reach in and fetch the parsed format string to use for yourself.
I start to learn C++ from C. Recently, I have just read a tutorial book about C++. In section Introduce to streams, the book has noted:
The << operator is overloaded so that the operand on the right can be
a string or any primitive value. If this operand is not a string, the
<< operator converts it to string form before sending it to the output
stream.
So I wonder whether printf() function in C has the same effect. And if it doesn't, please tell me about the differences between both of them.
Well, of course it has to somehow generate a string representation of each argument, that is needed in order to have something to print. Printing involves sending streams of characters to an output device after all, you can't print unless you have a sequence of characters.
The printf() function uses the formatting string to control how to interpret each argument in order to create the character representation, and also how to format that representation when output.
Note that no "conversion" of the arguments happens that is visible externally, of course. There's no way
printf("%d\n", 47);
can make that 47 into a string in place; C uses call by value so the function only gets a copy of the value, and it then uses the type information implicit in the %d conversion specifier to figure out how to generate the two characters '4' and '7' that make up the printed representation.
So I wonder whether printf() function in C has the same effect.
Both C and C++ uses streams for output. In C it is stdout and in C++ it is cout.
Though it is not evident from the statement printf writes to standard output(stdout) say a terminal.
In case of cout, it is evident from a statement itself, where the output is going.
Some subtle differences
With cout you might need to include an additional header - say iomanip - and use some functions - say setw() - to have fine formatting where as in printf you rely on format string.
Performance - Each has its own advantage depending on what you print and where you print. I borrowed this point from here.
Another similarity
Both C++ and C standards mention nothing about the order of evaluation of function arguments. So you must not try fancy stuff with functions. For example neither should you do
printf(%d%d",++i,i++); // The behaviour is undefined.
nor should you do
cout<<++i<<++i; // The behaviour is undefined.
Note:
Remember that the c streams are available in C++ if you include the necessary headers.
In my code I used fprintf. I used flawfinder to check the code for vulnerabilities and I got that:
358: [4] (format) fprintf: If format strings can be influenced by
an attacker, they can be exploited. Use a constant for the format
specification.
Can someone explain to me what Use a constant for the format specification actually means? Is there any safe version of fprintf?
The problem is that fprintf determines how many arguments it should get by examining the format string. If the format string doesn't agree with the actual arguments, you have undefined behavior which can manifest as a security vulnerability.
The problem is particularly bad if the string supplied can be influenced by the user of your program, because he can then specifically design the string to make your program do bad things.
There is no safe version of fprintf in the C standard. C++ streams avoid the problem, at the cost of not having format strings and using a far more verbose syntax for specifying formatting options.
A constant string, as in a string literal.
Like in
fprintf(someFile, "%s", someStringVariable);
and not like
fprintf(someFile, someStringVariable);
It means it wants you to write:
fprintf(out, "foo %s", some_string);
instead of what you have, which I guess is something like:
const char *format = "foo %s";
/* some time later */
fprintf(out, format, some_string);
The reason is that it's worried format might come from user input or something, and a malicious user could supply a format foo %s%s%s in order to provoke undefined behavior that they may be able to exploit.
Obviously if you're choosing between n different format strings, all of which are string literals in your code and all use the same format specifiers, but you choose which one at runtime, then following this advice is a bit awkward and wouldn't make your code any safer. But you could have n functions instead of n strings, and each function calls fprintf with a different string literal.
If you're reading the format string out of a config file (which is one fairly crude way of implementing internationalization from scratch) then you're basically out of luck. The linter doesn't trust your translator to use the right format codes for the arguments supplied to the call. And arguably neither should you :-)