-1

i am creating my onw strlen function which it's going to be a public function and it's for x64 ...

now i have a question about passing string address to this function ... this function get the string address using RAX register ... now i want to know that is it really necessary to check the provided address is equal to NULL (0) or not ? because string address can be anything and if even the provided address is invalid, crash will happen ! and it's not really necessary to do this at the top of function:

test rax, rax        ; string-address == 0 (NULL) ?
jz   .ret0

so in public functions, is it really necessary to check the provided address whether is equal to 0 ? because i think it's an extra action !!!! (even for public functions)

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
ELHASKSERVERS
  • 195
  • 1
  • 10
  • 1
    Please consider first finishing your previous questions before asking a new one. You've just left those who tried to help you hanging with no clear conclusion. – fuz Feb 28 '20 at 12:46
  • 2
    What do you mean by "public function"? There are many functions provided by the C-standard which have undefined behavior if a nullptr is passed (including `strlen` --> https://stackoverflow.com/questions/5796103/strlen-not-checking-for-null). – chtz Feb 28 '20 at 14:21
  • "is it really necessary to check the provided address whether is equal to 0" what is your definition of necessary? – Erik Eidt Feb 28 '20 at 15:48
  • "im asking that is it enough to just check the lower 32-BIT of an address or it's important to check the whole 64-bit ?" Let's take your question to the logical extreme: why not just check the low 8 bits `test al, al`, or maybe even just the lowest bit. – Erik Eidt Feb 28 '20 at 15:49

2 Answers2

1

This depends on what your function shall do:

In many APIs passing a NULL pointer shall have some certain effect. For example, you wish that your function returns -1 if a NULL pointer is passed.

In this case you must add that check.

Maybe you run your program on an operating system where the address 0 is a valid address. (This is not the case when using modern OSs, but under old (1996) Linux versions this could have been the case).

In this case your strlen() implementation shall also work if the first character of the string is stored at address 0.

This means that you must not add that check in this case.

Martin Rosenau
  • 17,897
  • 3
  • 19
  • 38
  • thank you for your answer ... in the most modern software, programmer knows that his addresses are valid because he checks them in his cycle ... so i think an other checking level is an extra action anyway ... because we just check an address is equal to 0 or not !!! the provided address might be even a wrong address so we can't check that !!!! so still there will be a problem and checking for 0 is extra (i think as i said (reason)) – ELHASKSERVERS Feb 28 '20 at 19:33
1

In ISO C, calling the standard function strlen with a NULL pointer is Undefined Behaviour. This doesn't require/guarantee a crash, it merely means that's a possibility. (And so are demons flying out of your nose). UB means literally anything can happen (without violating the standard).

Obviously in practice the set of things which can actually happen is usually not that large, and of course most OSes don't even let you map the zero page at all. (And most C/C++ implementations use the bit-pattern 0 as the object-representation for nullptr / NULL, same as the C/C++ source-level 0, even though fun fact that's not required.)

So most strlen implementations simply start by loading the first byte. (Or if it won't cross a page, load the first 16 bytes to branchlessly check for zero with SSE2. Is it safe to read past the end of a buffer within the same page on x86 and x64? has some discussion of glibc's x86-64 asm strlen implementations.)

If the caller wants to avoid crashing on NULL pointers, check before calling.

It's perfectly valid to write function without a nullptr check, as long as that part of the contract is made clear to people writing code that calls it.

If you're writing by hand in asm (presumably for performance reasons), yes you should avoid writing extra sanity-checks that aren't needed, unless there's some useful behaviour that you could actually factor out of several callers, into a wrapper for strlen. (e.g. that falls into normal unchecked strlen for non-NULL, so it's just an extra couple instructions ahead of the normal strlen label.)

Besides, what could you return that would be any use to your caller for a NULL input? 0 implies that it's safe to read ptr[0] and find a '\0'. Maybe that's ok for some callers. size_t is an unsigned type so every other possible value is positive and also a valid size.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847