<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by @binaryfox on Medium]]></title>
        <description><![CDATA[Stories by @binaryfox on Medium]]></description>
        <link>https://medium.com/@binaryfox?source=rss-e11abffc8803------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/0*SR15OslLnBFqGZhF.png</url>
            <title>Stories by @binaryfox on Medium</title>
            <link>https://medium.com/@binaryfox?source=rss-e11abffc8803------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sun, 24 May 2026 02:26:18 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@binaryfox/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[Photos from Biggest Little Fur Con 2015]]></title>
            <link>https://medium.com/@binaryfox/biggest-little-fur-con-2015-a4e7cb327839?source=rss-e11abffc8803------2</link>
            <guid isPermaLink="false">https://medium.com/p/a4e7cb327839</guid>
            <dc:creator><![CDATA[@binaryfox]]></dc:creator>
            <pubDate>Tue, 02 Jun 2015 04:32:10 GMT</pubDate>
            <atom:updated>2015-06-02T04:32:42.761Z</atom:updated>
            <cc:license>https://creativecommons.org/licenses/by-nc-sa/4.0/</cc:license>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*PnzsgNggRykJok6ODbJZlQ.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*YcfanA-4GVeGu4KA6EgCLA.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/850/1*aGG2xq8jORMzjxbVPVNREw.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*HgtoOB2Pgii7Ff3F0fVOKA.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*pnewcXyxpcfQIH_FONkm6g.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/850/1*xEJYX9NEhhEBFPqdrgHtvw.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Pa4dyrSnwzF2U3K3bE-K0w.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*obJyqTJX6mMclofp0xbQbg.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*GzeDPUeNnOJu0hrYTm5Ihg.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*hu0QGxXTZJokEvu_2dQPLA.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*IJmDXfo7iCWccOjMrFP4_w.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*vqvdfihSbdXHqjEaYkiVjw.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*XkJgA0u_oNnUdSCtgkS-nA.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*E9L7tlOaEtc73p8d9Jobdg.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*mqVic0j8Ydk1wCU4Cs_TNA.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*dkvkAILVSVxN5X8hA7Uxvw.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*u5HFmEh1hJVcf_pn5V03BQ.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/850/1*6rx47KhR8gYPlITkxSz27w.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Yl2qck7UM3WES-m7GjDVAw.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*0CZUnaLefxMk1EW7PSajPg.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ux6ZOMffTaVROFf8eKq2jA.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*W3zxKzHKSLzhz6iy0qbLbQ.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*iy2WfHwx49EzLtQSd3pkVg.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/850/1*jezsV0Soz7o51XUSpx7OrA.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Hh0J3HT5nsK-k5vTY8u1LQ.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*neX5d0BEY0DQ0ziKqwlwew.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*qtsXlGZIlsa6rB_q_9c2Tg.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*-x8RIETPNVaK_Bjj70Rwkg.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*gWKZPfmSPT4jR-EE6sheZw.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*y71HBwvEUnWfdsyXPIZCGQ.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*0kG-Zl-44vSNWB6OJYKhxQ.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*W66Jq8wCxCosyKabz6dKUQ.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*GW6YhoRpaMOco9DIPHHkdg.jpeg" /></figure><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=a4e7cb327839" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Photos from Further Confusion 2015]]></title>
            <link>https://medium.com/@binaryfox/photos-from-further-confusion-2015-fbfb840e475d?source=rss-e11abffc8803------2</link>
            <guid isPermaLink="false">https://medium.com/p/fbfb840e475d</guid>
            <dc:creator><![CDATA[@binaryfox]]></dc:creator>
            <pubDate>Wed, 21 Jan 2015 06:50:03 GMT</pubDate>
            <atom:updated>2015-01-21T06:50:03.869Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*L4rSqJ7HDzH84ob5am4NZQ.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*nrKy2dIacXcA-dS6J6dESA.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*L84i-ly8CBuHEI7EeWFPkQ.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*NvtexyHyqIJLaaDAMg6x2w.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*rr-u109y3V0CBBA7W-Xalg.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ySxgGHGKmgA-a9f0uW_mqw.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/850/1*TX4y_k25TYqXKxDY27aNKA.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*lTnsHhHEppAHMisiBKkomA.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*GN_KImYh3O7KJJnq7xIxmQ.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/850/1*Jrt-kIYajrLANUqVyIzhKQ.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ZON143K4I6XnSDjnxYr2Tg.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*f9Cr162izQqNIkczrgwtsA.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*KUaktDB4DTGvWXgyag0O_w.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*KzSGarAOcr_PQBcPqyeVXw.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*R_q-IPl22J9d8qmEx5q1qw.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ssnGwHWKuEhGKJAj8KDvAQ.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*PbYTIriB2m5n9wY9sjb1fg.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/850/1*KAj7Saj9JDp_bum1mAIsFA.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*sdV58JMGxEViK04mx7C_3w.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ZpqBaiAZI4LY2ViiTj0ZlA.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*wiaO97BPKlfG_GmaEudqCw.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*yCvMrN7IxNJsodluWiRr-w.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/915/1*yDpeDGvVZ_PdA6b6ImwySg.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*lUDBBnIZ38qUr9aXYFJm0w.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*f0naQ8xq1J_VqM1pM1x7UQ.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*HrmxvH26tsb54pof5rDvcA.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*GRouE4_6wDLkd4KDuKUPxA.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*3gzLwWO5lyguA9OqGaDB7Q.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*juhAwdaajZ4srGa-DuIi-g.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*kmdJX7SlIC3Bz6fALKRK8w.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*eGzFRC1mGIM9Z8qu2nMugw.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/914/1*JPQF3V2cJi1-mhfxHwp_bw.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*DInu-OWF7c_kWxvRtyP4gg.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*vMZcCvaUhO6dR__nwtZTQg.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*LiycE_Mo3DDJRIz5yYnYnw.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*lN4kPjn4iFox-VcysJutBA.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*BlEom1xajkn9BOUIhSKEug.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*lck3Kj5AV_zGikCPGVNYRg.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ViJBrIqmOqt-z2yZEc7avg.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*J7rEdBlkC_ugWyRm8IoCDg.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/914/1*ZY37YkI49VkJSqKkbGOuiQ.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/914/1*ac0cFP-nFWGZg4j5hTJWgQ.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*qXhrydbxNajLxcjMzPvPDA.jpeg" /></figure><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=fbfb840e475d" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Comparing the Invisible]]></title>
            <link>https://medium.com/@binaryfox/comparing-the-invisible-8353707264b4?source=rss-e11abffc8803------2</link>
            <guid isPermaLink="false">https://medium.com/p/8353707264b4</guid>
            <dc:creator><![CDATA[@binaryfox]]></dc:creator>
            <pubDate>Sun, 27 Apr 2014 21:10:46 GMT</pubDate>
            <atom:updated>2014-04-27T23:45:13.902Z</atom:updated>
            <content:encoded><![CDATA[<h4>A lesson on undefined behavior in the C language</h4><p>Below is a piece of code similar to something I was working with last week. Please bare with me on the simplicity of this example. I know that modern applications should not use 32-bit integers to store IP addresses because of IPv6 compatibility.</p><pre>#include &lt;stdint.h&gt;<br>#include &lt;string.h&gt;</pre><pre>typedef struct Address {<br>    uint32_t ip;<br>    uint16_t port;<br>} Address;</pre><pre>typedef struct Entry {<br>    Address address;<br>    Connection *connection;<br>} Entry;</pre><pre>typedef struct Connection Connection;</pre><pre>Connection *FindConnection(const Address *address,<br>                           Entry *connections,<br>                           size_t nConnections) {<br>    for (size_t i = 0; i &lt; nConnections; ++i) {<br>        if (memcmp(address,<br>                   &amp;connections[i].address,<br>                   sizeof *address) == 0) {<br>            return connections[i].connection;<br>        }<br>    }<br>    return NULL;<br>}</pre><p>Have you seen what’s wrong with this function? It seems simple enough. Iterate through an array of entries in some kind of connection table looking for the one with the matching IP address and port number. What could be easier? Let’s use the function now.</p><pre>Address addr = { 0x7f000001, 80 };<br>Connection *conn = FindConnections(&amp;addr, conns, nCons);</pre><p>This code will work most of the time. To see why I said “most of the time” let’s first ask a question: What is sizeof *address in the function above? A quick test program will reveal the answer: 8</p><p>This may be a bit surprising but remember that each primitive variable type has an alignment requirement enforced upon it by the underlying architecture. A uint32_t must always have a memory address divisible by 4, a uint16_t must be at an address divisible by 2. If we construct an array of address structs in order for the the uint32_t inside of each to be aligned the compiler must add a little padding in between. Including the padding the size of the entire struct is 8. 6 bytes of data plus 2 bytes of padding. This brings us to the next question: What is the value of these two bytes? To answer this lets look at the assembly generated by the statement that initializes addr above:</p><pre>movl    $2130706433, -16(%rbp)<br>movw    $80, -12(%rbp)</pre><p>The variable addr consists of two values, 2130706433 (which is simply the decimal form of the hexadecimal value 7F000001) and 80. These are copied onto the function’s stack at 16 bytes before the %rbp (which is the stack base pointer) and 12 bytes before %rbp. “movl” copies 4 bytes, a “long word,” and “movw” copies 2 bytes, a word. (For the curious, on x86 8 bytes is a “quad word” and is abbreviated “q” and 1 byte is a “half word” and abbreviated “h”.) Since the struct is 8 bytes long in total we can see that it exists in the 8 bytes between %rbp-16 and %rbp-8. But wait! We’ve only copied 6 bytes! This is where the problem lies. Initializing a struct using this syntax leaves the padding bytes uninitialized. Quoting the C99 specification:</p><blockquote>When a value is stored in an object of structure or union type, including in a member object, the bytes of the object representation that correspond to any padding bytes take unspecified values.</blockquote><p>Now we understand why this code doesn’t work sometimes. C doesn’t guarantee anything about the padding bytes but in the memcmp call we compare the entire struct, including the padding. Since the padding is uninitialized it could be any two random bytes that happened to be there when the variable was initialized. Most of the time they will be zero but every once in a while they will be something else and the code will mysteriously fail to find a connection entry which may otherwise appear to be present.</p><p>How can we catch this before it causes random failures? Running the program under a memory checker such as Valgrind will alert you to comparisons which use uninitialized values. Here’s what the failure looks like:</p><pre>Conditional jump or move depends on uninitialised value(s)<br>   at 0x4C2EB32: bcmp (mc_replace_strmem.c:930)<br>   by 0x400602: FindConnection (test.c:19)<br>   by 0x4006A7: main (test.c:37)</pre><p>Valgrind is complaining here that bcmp (which is the function behind memcmp above) is branching based on an uninitialized value. While it causes your application to slow down by a factor of 10 or more Valgrind is a very useful tool for detecting silent errors that may become bugs in the future.</p><p>How could we avoid this problem? The first answer is that maybe using memcmp wasn’t a good idea. As we’ve seen using it this way makes some assumptions about how the compiler is laying out memory that might not hold true in all circumstances. Explicitly comparing the IP and port fields will generate the correct code and may actually be faster since it isn’t calling a generic function like memcmp. Another way to avoid this is to make the padding bytes explicit like this:</p><pre>typedef struct Address {<br>    uint32_t ip;<br>    uint16_t port;<br>    uint16_t padding;<br>} Address;</pre><p>Why does this make a difference? First, the structure is still 8 bytes. All of the uint32_t’s can easily fall on 4 byte boundaries and uint16_t’s on 2 byte boundaries. Does the initialization style we used above still work? Yes. C allows struct initialization to omit some fields. In fact, it does exactly what we want.</p><blockquote>If there are fewer initializers in a brace-enclosed list than there are elements or members of an aggregate, or fewer characters in a string literal used to initialize an array of known size than there are elements in the array, the remainder of the aggregate shall be initialized implicitly the same as objects that have static storage duration.</blockquote><p>The language is a little convoluted but “objects that have static storage duration” are initialized to zero so our unlisted padding field will be zeroed as well. Let’s check out the assembly again to be sure.</p><pre>movq    $0, -16(%rbp)<br>movl    $2130706433, -16(%rbp)<br>movw    $80, -12(%rbp)</pre><p>This isn’t exactly what I was expecting but it makes sense. By writing zero as an 8-byte value over the entire variable each field is initialized to zero. Then the two fields we have explicitly given values to are set as before.</p><p>What is the lesson to be learned here? C gives the programmer almost complete control over almost all of the low level details of the system executes their code but this control comes at a price. The programmer must understand how the low level details work or else code which, at a high level, seems to be correct may not do what they intend.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=8353707264b4" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Is a Twitter Client Worth $20?]]></title>
            <link>https://medium.com/@binaryfox/is-a-twitter-client-worth-20-c8245e34214e?source=rss-e11abffc8803------2</link>
            <guid isPermaLink="false">https://medium.com/p/c8245e34214e</guid>
            <dc:creator><![CDATA[@binaryfox]]></dc:creator>
            <pubDate>Sat, 01 Mar 2014 23:47:52 GMT</pubDate>
            <atom:updated>2014-03-01T23:47:52.651Z</atom:updated>
            <content:encoded><![CDATA[<h4>Deciding whether or not to buy TweetBot.</h4><p>After fighting with TweetDeck to post a picture: Why can’t I drag-and-drop it into the compose widget? Why must I manually resize it so that it’s under 3MB? I decided it might be time to choose a better Twitter client. This brings me around to TweetBot.</p><p>As far as I can tell TweetBot is the best Twitter client available for OS X. It supports the feature for which I use TweetDeck over Twitter’s offical client: multiple columns. The one sticking point for me is the price. Compared to every other Twitter app I’ve used, which were free, TweetBot costs infinitely more: $19.99. In the grand scheme of my budget though $20 isn’t very much but I tend to give a reasonable amount of thought to non-food items that cost more than a few dollars so here are some things I compared it to:</p><ul><li>Dinner out at a restaurant can easily approach or exceed $20 including tax, tip, beverages and appetizers.</li><li>If I’d bought TweetBot when I first started using Twitter I would have paid, on average, half a cent for each of my 3,875 tweets.</li><li>Based on download size TweetBot is $3.77 per MB, compared to $0.34 per MB for one of my employer’s products.</li><li>A new release on iTunes is also usually around $19.99. In comparison I will probably spend more than 120 minutes paying attention to TweetBot.</li></ul><p>I could keep going like this but the comparisons would begin to get silly. In the end I’m going to buy TweetBot. I think the point of this story is that it’s pretty hard to decide on the value of a software program. App stores these days tend to sell things for either free, cheap (1¢ — $2) or expensive (more than $2) compared to old-fashioned boxed software which I recall usually started at $20 and sometimes made it to the bargain bin at $5 — $15. On top of this, if I pay $19.99 for TweetBot now they will never get another cent from me because the Mac App Store doesn’t (currently) charge for updates. Heck, Apple released OS X Mavericks, the product of tens of thousands of man-hours of work (at least), for no cost what-so-ever.</p><p>With all of this in mind all I can say is that I have no idea how much software is really worth.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=c8245e34214e" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>