The world/other character is being mixed with the user.
Swap the "on" value for world/other and user.
Always reset the "what" value before starting the condition loop.
Turns out that the previous code does not support the form "u+rw-x".
The following is an alternative way to write this that previously worked "u+rw,u-x".
Make sure both methods are supported by adding an additional check for the "+", "-", and "=".
When adding and removing, the previous opposing bits needs to be reset.
For example "u+rwx-r" should set the "add read" bit and then remove the "add read" bit while setting the "subtract read" bit.
Also absurd forms like the following need to work: "u+rrrrrwx+rwwwxwrwrwrwww" or "u+rwx,g-rwx+wrrr,o+rwx-wwr".
A copy and paste mistake in f_file_mode_to_mode() results in the wrong bits being set for the world bits.
Don't operate on the parameters directly.
Update them only on success.
This ensures a safer design at a cost of slightly more resources being used.
Swap the world and the owner bits for replace to make it more logically consistent in the order of the bits.
Hopefully this will make things slightly less confusing.