News for hackers. Stuff that matters.
Re:Banned C standard library functions in Git source code by asveikau on Sunday August 25, 2019 @11:18AM (#20793431)
I don't see a huge problem with strtok as long as it isn't a multi threaded program. It is not in gets territory which is literally impossible to use correctly.
Re:Banned C standard library functions in Git source code by bhk on Sunday August 25, 2019 @11:56AM (#20793625)
Synchronous reentry is a problem. Say some loop using strtok calls a function... how do you know that that function doesn't use strtok (or call another function that does...).

Any use of non-const static variables in general has this problem, and strtok is just one example.

Re:Banned C standard library functions in Git source code by derefr on Sunday August 25, 2019 @01:02PM (#20794017)
> Say some loop using strtok calls a function... how do you know that that function doesn't use strtok (or call another function that does...).

I’m constantly surprised that C isn’t specified in such a way that lack-of-reentrancy can be determined at compile time. You’d “just” need a symbol table, sort of like the debug symbol table, in each compiled object, holding for each visible symbol the set of function calls marked `__no_reenter` that are predominated by that symbol in control flow. (Yes, some functions do computed jumps, like with longjmp. Just implicitly label those functions __no_reenter unless the programmer explicitly labels them __reenter!)

Re:Banned C standard library functions in Git source code by asveikau on Sunday August 25, 2019 @01:23PM (#20794158)
The problem isn't exactly reentry. It's that the function, having already exited, has modified global state, and it needs the same state to be there on the next call. If another call is interleaved (another callee with its own strtok loop) then the state is overwritten with the inner loop, and your own next call won't have its expected contents.

Whereas with a term like reentry I think of two strtok frames on the stack at the same time, which is not possible.

I think it's a bit easier to conceptualize with a function that produces a simple return value in a static buffer. Take getpwnam(). It fills a global structure with info about a given user. So you may keep a pointer to that on your stack. Then you call some other function foo(). foo looks up another user. Suddenly you can't rely on that other call to getpwnam() not having overwritten the data in the result you got back the first time.

Re:Banned C standard library functions in Git source code by bhk on Sunday August 25, 2019 @01:33PM (#20794243)
Ah, yes. What I described wasn't reentry. A reentrant function using strtok could exhibit this problem, but it applies more widely than that.
Re:Banned C standard library functions in Git source code by userbinator on Sunday August 25, 2019 @02:02PM (#20794444)
how do you know that that function doesn't use strtok (or call another function that does...).

The same way you know a lot of other things about the codebase: By reading and understanding it. Given what strtok() is used for, it's almost always going to be working on a single context at any one time.

Re:Banned C standard library functions in Git source code by bhk on Sunday August 25, 2019 @09:41PM (#20796878)
First, many C projects are libraries that are written for reuse in other programs. So "the codebase" is an arbitrary, unknowable thing. We don't have the ability to look at all the other code that will eventually coexist in the same process.

Second, code changes over time. Assuming you inspect 100 lines of code to ensure that they don't call strtok() ... do you sprinkle comments all over as a warning to future programmers not to add any calls to strtok()?

Finally, assuming we could evaluate all of the code in a program at once, it is impractical to build non-trivial programs that way. Instead, we rely on contracts. The idea is that if a caller conforms to its end of the contract, the callee will conform to its end. This allows us to reason about correctness of some code without reading all the other code in the universe and thinking through all the potential code paths. Any function using strtok() would be presenting a rather ugly contract clause "this function destroys strtok's static state". Even worse, such a clause would be contagious, infecting any client of that function, and so on.

Re:Banned C standard library functions in Git source code by missblit on Sunday August 25, 2019 @01:23PM (#20794161)
Might as well just use strtok_r everywhere and not worry about if you're using strok safely or not.
Re:Banned C standard library functions in Git source code by lholden on Sunday August 25, 2019 @11:48AM (#20793567)
"I don't see a huge problem with insert thing here as long as it isn't a multi threaded program."

Usually a bad omen. :)

Re:Banned C standard library functions in Git source code by slovenlyrobot on Sunday August 25, 2019 @11:26AM (#20793478)
I can't remember what's wrong with it, but it's responsible for about eleventy billion CVEs over the years
Re:Banned C standard library functions in Git source code by tropo on Monday August 26, 2019 @04:56PM (#20803683)
You can safely use gets on trusted input. For example, your program might create a pipe or socketpair to communicate between the processes that result from a call to fork. The stdout of one process feeds into the stdout of the other process.

Unless you have an insane gets implementation that writes the bytes backwards, you can also safely use it on untrusted input. Simply place a guard page at the end of the buffer. You can do the call from a forked child that you let die, taking notice of the problem in the parent. On systems without threading (because of locks in libc) you can do a longjmp to recover.

Re:Banned C standard library functions in Git source code by tlb on Sunday August 25, 2019 @12:08PM (#20793702)
git does use multiple threads for some longer operations, like gc and pack, so using strtok would be a disaster.