Checking data behind the pointer at runtime to avoid segfaults: (wchar_t *) vs. (char *)

I have a function printf

that can handle transforms %s

( char *

) and %ls

( wchar_t *

). Everything works fine if I pass in the correct argument for the correct conv pointer.

But if I pass it to char *

my function when it expects wchar_t *

, it might segfault (the null-terminated byte is, for example, in the second byte wchar_t

). Since I am referring to this argument via va_arg()

, I cannot be sure of the type.

If I believe that this array is char

always NUL terminated, I can check byte after byte to properly handle the NUL terminated char and stop memory access after it. But then I wouldn't be able to handle valid values wchar_t

like this:

0b XXXXXXXX XXXXXXXX 00000000 XXXXXXXX

      

I am already using the __attribute__

GNU C printf extension . But I can use this function through a python program through ctypes

, so the format / type check during compilation may not be enough.

Is there a way to do this kind of check at runtime in my C function?

(NB: "There is no such way" may be the answer, but I still ask to be completely sure.)

+3


source to share


1 answer


No, It is Immpossible.

In a typical C implementation, the type system exists only as a compile-time aid. * At runtime, all you have are data bytes, and there is no way to even point to a pointer to a number (beyond educated guesses).



Technically, you do not even allowed va_arg(ap, const char*)

, and then examine the memory, if the original argument was not char*

, signed char*

, unsigned char*

or void*

, or const

-linked version of this type. The type passed to va_arg

must always be a compatible type. (One reason for the lack of guarantee pointers for different types is the same size, layout, and value.)

(* In C ++ there is a bit more history there, because the data representing the types is stored, associated with polymorphic objects to make dynamic_cast

and typeid

work correctly, and associated with all objects, exceptions to make catch

blocks work correctly, but none of this is compatible with va_arg

.)

+2


source







All Articles