
Ask HN: (CloudFlare bug) - Why does write() in C allow negative length? - winteriscoming
In context of the CloudFare fiasco, the bug report[1] states this<p>&gt;&gt; My current theory is that they had some code in their &quot;ScrapeShield&quot; feature that did something like this:<p>&gt;&gt; int Length = ObfuscateEmailAddressesInHtml(&amp;OutputBuffer, CachedPage);<p>&gt;&gt; write(fd, OutputBuffer, Length);<p>&gt;&gt; But they weren&#x27;t checking if the obfuscation parsers returned a negative value because of malformed HTML. This would explain the data I&#x27;m seeing.<p>I haven&#x27;t used C in my professional career (I mainly use Java), so the fact that this function allowed a negative value, for &quot;num bytes to write&quot;, to be passed to it and then even went on to write data without throwing an error for passing a negative value baffles me. I&#x27;m genuinely curious why this function doesn&#x27;t throw an error for negative &quot;num bytes to write&quot;. Is there any use case which I&#x27;m missing where it would be valid to send a negative value and expect it to write negative number of bytes?<p>[1] https:&#x2F;&#x2F;bugs.chromium.org&#x2F;p&#x2F;project-zero&#x2F;issues&#x2F;detail?id=1139
======
technion
I've written a gist that somewhat explains this:

[https://gist.github.com/technion/a16095fa6e3a027d6bc938ad6f9...](https://gist.github.com/technion/a16095fa6e3a027d6bc938ad6f9bdc50)

write() doesn't "print a negative number", as per the man page, write(2) takes
a size_t for an argument. And what that means is explained if you run that
gist:

    
    
        We have a count of 18446744073709551611 and will write that many characters
    

In short, you're looking at a signed, negative integer, cast to a very large
positive integer. clang will only print a warning if you compile with
-Wconversion and whilst I like to do that in my own code, most people find
that too noisy.

Edit: Personally, I feel this "email obfuscation feature" should never have
been written in the first place. There are a myriad of options for people to
do this in their own website without something this obviously complex being
built into an nginx module of a CDN.

~~~
winteriscoming
I see what you are saying. So that function actually accepts a size_t which is
a unsigned type. I now understand why this call to the function went through
without any exceptions. When I posted my question, I was referring to this
page[1] which claims the type for the "numBytes" to be a signed integer.

[1]
[https://www.lix.polytechnique.fr/~liberti/public/computing/p...](https://www.lix.polytechnique.fr/~liberti/public/computing/prog/c/C/FUNCTIONS/write.html)

~~~
technion
I'm going to assume this is an age thing, because the example linked on that
page has a date of 1996.

This is more accurate for every platform I've actually worked with:

[http://man7.org/linux/man-pages/man2/write.2.html](http://man7.org/linux/man-
pages/man2/write.2.html)

~~~
LastSeagull
Hello, I understand your example, but when putting

    
    
         write(fd, buf, count);
    

inside your my_write function... it doesn't work. Is there something more?
Thank you.

