1

strtrns has the following descriptions: desc-1, desc-2

The strtrns() function transforms string and copies it into result. Any character that appears in old is replaced with the character in the same position in new. The new result is returned. .........

This function is a security risk because it is possible to overflow the newString buffer. If the currentString buffer is larger than the newString buffer, then an overflow will occur.

And this is its prototype( or "signature"? ":

char * strtrns(const char *string, const char *old, const char *new, char *result); 

I've been googling to no avail. I appreciate any tips or advice.

2
  • 1
    Not to be too pedantic, but why doesn't your description match the signature (oldsegment/newsegment/newString/currentString don't match anything) Commented Feb 13, 2012 at 17:28
  • You can't be too pedantic! I gotta learn this well! Thank You, Commented Feb 13, 2012 at 17:30

3 Answers 3

3

I think you can write your own safe one pretty quickly.

It won't be a direct replacement, as the signature is slightly different, and it will allocate memory that the caller must free, but it can serve mostly the same job.

(I'm also changing the parameter name new, which is a reserved word in C++, and the parameter string which is a very common type in C++.
These changes makes the function compatible with C++ code as well)

char* alloc_strtrns(const char *srcstr, const char *oldtxt, const char *newtxt) { if (strlen(oldtxt) != strlen(newtxt)) { return NULL; /* Old and New lengths MUST match */ } char* result = strdup(srcstr); /* TODO: check for NULL */ /* Caller is responsible for freeing! */ return strtrns(srcstr, oldtxt, newtxt, result); } 
Sign up to request clarification or add additional context in comments.

7 Comments

Are you sure that the result string of strtrns can be a different length than the input? According to the man page, it simply is a direct character-by-character replacement, which means the result would be the exact same length as the original string. Also, the first call in here to strtrns might crash since the new string is zero length. The one implementation of strtrns I looked at assumed that the new and old buffers were the same length. One other potential issue is that this can't be a direct replacement since the caller must free the result in this version.
@MarkWilkins: Interesting, I did find conflicting documentation of strtrns, some saying it does a 1-to-1 character replacement, and some saying it does a string-based "search-and-replace". I guess I can't be sure what implementation OP Adel has.
@abelenky: The link to a man page in the OP seems to indicate the former (1-to-1 replacement).
I wouldn't recommend this, as the memory allocation is a quite large side-effect. I'm all for writing your own function, but I'd recommend adding a limit parameter instead.
@Tobias: In working with the original strtrns, you pretty much need to allocate your own memory (unless referring to stack-space, or pre-allocated memory). I don't see that it matters so much if the caller or the callee makes the allocation. Either way, it must (generally) be made.
|
3

The claim that this function is unsafe is nonsense. In C, whenever you have an interface that takes a pointer to a buffer and fills it with some amount of data, you must have a contract between the caller and callee regarding the buffer size. For some functions where the caller cannot know in advance how much data the callee will write, the most logical interface design (contract) is to have the caller pass the buffer size to the callee and have the callee return an error or truncate the data if the buffer is too small. But for functions like strcpy or in your case strtrns where the number of output bytes is a trivial function (like the identity function) of the number of input bytes, it makes perfectly good sense for the contract to simply be that the output buffer provided by the caller must be at least as large as the input buffer.

Anyone who is not comfortable with strict adherence to interface contracts should not be writing C. There is really no way around this; adding complex bounds-checking interfaces certainly does not solve the problem but just shifts around the nature of the contracts you have to follow.

By the way, strtrns is not a standard function anyway so if you'd prefer a different contract anyway you might be better off writing your own similar function. This would increase portability too.

1 Comment

R.. - thanks for this - it's what people seem to forget about C - you're given enough rope to hang yourself (or not) as you see fit (and are capable) - There is no such thing as 'entry level' C
1

You don't really have any options in C. You simply have to ensure that the destination buffer is large enough.

3 Comments

Uhhh.... No options? How hard would it be, in C, to rewrite this little function? Personally, I've had times when I had to write snprintf(), so I think it can be done.
Of course it can be rewritten, but I interpreted the question as the OP wanted to know of alternative functions.
You've got to be careful on SO, not to open the door to C bashing. As you can see, I've been here a while, so I have moved on from careful to paranoid. :)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.