Sunday, May 18, 2014

What Happens When Your Phone Falls into the Ocean

Short answer: It'll stop working.

But have you wondered, why? What happens to the insides of the phone?

We've all heard that salt water conducts electricity and "fries" your electronics, but what does that mean? Will the phone rust? Will the battery melt? Today we get to find out!

In this blog post we'll look inside my Black 16GB iPhone 5 (yes, that's an affiliate link) that took a swim in the Pacific. Where possible, iFixit's iPhone 5 teardown pictures will model what iPhone 5 internals should look like.

The Initial Opening

This is how an iPhone 5 looks like after swimming in the Pacific.
This is how iPhone 5 innards should look like, courtsey of iFixit.

Right away, there's a huge difference. There ocean phone is full of fine sand, salt stains, and a giant rust spot. If you remember chemistry class, then the rust spot makes sense: rust is an electrical process. The biggest rust spot will be at the anode of the battery leads, which is exactly where it is.

The Screen Assembly and Mainboard

The salted, rusty screen assembly. The rust feels like its simply rubbed off from the other part.
The salted, rusty mainboard and battery. The battery is surprisingly intact.
How an iPhone 5 screen assembly and mainboard should look like. Notice the distinct lack of salt, rust, and sand. Courtesy of iFixit.

Once again, the salt stains and rust is the big difference. Surprisingly, the lithium-ion battery is perfectly intact, without holes or burn damage. Why surprising? Lithium and water tend to react vigorously.

Battery Closeup

The battery leads are extra rusty.
An unsalted battery, courtesy of iFixit.

Other than the rusty leads, the battery seems fine from the outside. The phone would not power on, but I am not sure if its related to the battery or other electronics failures. Probably both.

Mainboard and Chassis Closeup

There's a large salt deposit under the mainboard.
The salt water must have pooled there as the phone dried. 
A pristine mainboard, courtesy of iFixit.

Getting to this part was a challenge: some of the screws were so corroded and rusted that unscrewing them stripped the grooves used for unscrewing. I had to resort to force and some prying, which didn't matter since the phone was already broken.

A Zoom on the Mainboard

A zoom on the corroded mainboard.
The front of the camera and mainboard.
A pristine mainboard, courtesy of iFixit.

Almost every connector is rusted or otherwise corroded. This is one of the main reason everything stops working: the small connectors corrode and the mainboard components can't make electrical contact.


All the rusted components in one glorious photo.
All the pristine components, courtesy of iFixit.

The obligatory "all components in one photo" shot. Mine isn't as nice as iFixit's, but the other differences should be obvious. The one interesting thing to note is the serious corrosion on the SIM card.


If your phone falls into the ocean, its going to have a bad time. Don't let your phone fall into the ocean.

Thursday, May 15, 2014

Bjarne Stroustrup on the Past and Future of C++ (Including Long Template Errors)

Someone on IRC pointed me to Bjarne Stroustrup's talk on C++11 and C++14 at Microsoft's Going Native 2013. If you work with C++ and haven't seen Bjarne's talk yet, go watch it now.

Stop reading this and go. I'll wait. 

An hour into the talk, Bjarne starts discussing templates, long error messages, and the tradeoffs that were made during the design of C++. The long error messages were a conscious decision to preserve performance and expressiveness with the computing power available back in the mid 1980s.

It amazed me that Bjarne admits template error messages are a huge debacle, and he has been working for 20 years to fix the problem. The solution is near: C++14 concepts will finally allow for sane template errors. Messages like "Member must be CopyAssignable" will be possible, and hopefully normal. This isn't just theory: there is an experimental branch of GCC that supports concepts right now.

Other parts of the talk are fascinating in their own right and have given me a lot more respect for C++ and Bjarne Stroustrup. The man could have rested after creating the original C++ spec and compiler, but he has been working for 20 years to improve the language. That dedication has made C++11 much better than C++98.

Bjarne also brings up a good point: many people who dislike C++ are using it the wrong way. The language should only be used when you need a performance and lightweight abstraction at the same time. If you don't care about performance or you need high-level abstraction, C++ is the wrong tool for the job.

The talk has a lot more interesting content. If you haven't watched it yet, go now.

Sunday, May 11, 2014

C++11: better, but still frustrating

Update: jduck pointed out that the before/after code snippets were identical. Oops. Now fixed.

I'd previously given up on C++ due to the many small frustrations: incomprehensible error messages, silly parsing issues (e.g. '>>'), rules to avoid subtle errors, and many other small frustrations that soured me on the language. That was back in the days of C++98 and C++03.

The language has evolved, and recently I found myself working on a project written in C++11. So far my experience has been better, but still frustrating.

A Motivating Example

I'll start with a real example. The project created a lot of Foo objects that were passed by reference to numerous functions. I needed to keep a collection of every Foo object that was passed to a specific function.

My first thought was, "I know, I'll create a vector of Foo&". This thought is simple, elegant, and of course, wrong.

A vector of references isn't possible because references can't be reassigned. That is, references[0] = foo; would update the referenced object, not the zeroth entry of the references vector. More technically, references are not CopyAssignable, a requirement for members of containers.

Errors Galore

But how would someone new to C++ know this? What do compilers say when making a vector of references? Lets find out by compiling this small (and wrong) program.

#include <vector>
#include <iostream>

int main(int argc, const char* argv[])
    int a = 1;
    std::vector<int&> test = {a};
    std::cout << "a: " << test[0] << std::endl;
    return 0;

Here are the results for Clang, GCC and MSVC:

Compiler Error List Error Count
Clang 158 lines
GCC 187 lines
MSVC 107 lines

In classic C++ style, the error messages are hundreds of error lines from obscure library implementation code. They give no indication of what is wrong, and no indication of the solution. I pity someone who doesn't have C++ experience trying to figure out what is wrong with their code. Pretty much any error would be more helpful, even an obscure message like "Member must be CopyAssignable" -- as long as it pointed out the correct line of code.

The Fix

For reference, the corrected program is:

#include <vector>
#include <iostream>
#include <functional>

int main(int argc, const char* argv[])
    int a = 1;
    std::vector<std::reference_wrapper<int>> test = {a};
    std::cout << "a: " << test[0] << std::endl;
    return 0;

The fix is to use the std::reference_wrapper utility function when making a container of references.


There's definitely upsides: the '>>' parse has finally been fixed. Classes can now be initialized with initializer lists. There is type inference via 'auto'. For-each style loops exist.

C++11 is a great improvement over C++03, but its still frustrating: the obvious solution (like containers of references) is wrong in subtle ways, and compilers still generate hundreds of obscure error messages for a one-character typo.

Tuesday, May 6, 2014

Do Not Reply Addresses Suck

If you send emails from do not reply addresses, I hate you.
Your customers hate you.
People you've never met also hate you.

Why  you should stop using no reply addresses:
  • Something will go wrong and your customers can't tell you.
  • You will send email to people who aren't your customers. They will have no way to ask you to stop.
Stop hating your current and future customers. Stop using no reply addresses. Only send email from monitored email addresses.

And one more thing...

If you create accounts without validating email addresses, I doubly hate you... and from now on I will be naming and shaming.

The Do Not Reply Hall of Shame lets people register without validating their email. The many follow-up emails are all from, please stop.

As you can guess, nothing was ever done., I hate you.

DataViz lets people buy software without verifying their email. Wish I could reply and tell them, but the email is from

My name is not Artem Dubov and I did not buy this software.

Saturday, February 8, 2014

Direct Download Link For Adobe Flash Player

Are you tired of seeing this?

"Error: Unable to proceed with the installation". Thats bad. But there's a green checkmark. Thats good? 

Do you find Adobe's toubleshooting page completely useless?
Then use this handy direct link and bypass Adobe's broken installer. As a bonus, it wont try to trick you into installing Lightroom or other unwanted products.

Current download link as of June 16, 2014:

Update the version string in the link as needed to get the flash player.

Sunday, January 5, 2014

Stupid IDN Tricks: Unicode Combining Characters (or http://░͇͇͇͇͇͇͇͇͇͇͇͇͇͇͇͇͇͇͇͇͇͇͇͇͇͇͇͇.ws)

Safari will display Unicode combining diacritical marks in the URL bar (try going to http://░͇͇͇͇͇͇͇͇͇͇͇͇͇͇͇͇͇͇͇͇͇͇͇͇͇͇͇͇.ws). It is possible to register domains with these marks. Some of these domains will look much like legitimate domains (e.g. vs. apple͢.com). This is probably not good.

Internationalized Domain Names (IDN)

DNS was only designed with 7-bit unsigned ASCII in mind. However, not everyone in the world speaks English, and they really want to type domains in their own language. So there is a terrible hack to map Unicode characters to 7-bit unsigned ASCII, called IDNA.

Homograph Attacks

Hopefully everyone has heard of homograph attacks using internationalized domain names. If not, here is a recap (taken from the Chrome wiki):
... different characters from different languages can look very similar, and this can make phishing attacks possible. For example, the Latin "a" looks a lot like the Cyrillic "а", so someone could register http://ebа (, which would easily be mistaken for This is called a homograph attack.

Defenses Against Homograph Attacks

There are multilayered solutions to the homograph attack:
  • Browser characters blacklists. These prevent you from registering characters that look like '/', and so on.
  • IDN character display rules (see: Firefox, Chrome). These rules restrict non-ASCII domain names to only those languages specifically configured by the user, and prevent display of mixed-language domains. For instance, if your have a Chinese installation of Windows then Chinese characters will be displayed for Chinese IDNs.
  • Registrar restrictions. Registrars will prevent you from registering a domain that combines  more than one language. So you can't register a name that is half English and half Russian, for instance.

Another Attempt

So how do we explain http://░͇͇͇͇͇͇͇͇͇͇͇͇͇͇͇͇͇͇͇͇͇͇͇͇͇͇͇͇.ws?

Defeating Registrar Restrictions

Registrars prohibit combining languages in domain names. But there are characters that aren't in any language. The most interesting of these are Unicode Combining Diacritical Marks. These unicode code points will modify the glyph right before them, instead of adding a new character. For example, the letter A when combined with U+0x332 will become: A̲.

But will these characters display in browsers?

Chrome: No :(
Firefox: No :(
Safari: Yes :)


Someone could register apple͢.com and it would display in Safari as:

This is not good.

Friday, December 6, 2013

I Hate (General Purpose) Computers

I hate computers. More specifically, general purpose computers. They cause me many hours of frustration, mostly due to malware.

Most people don't need or want the freedom to run the malware of their choice. They need a nice computing appliance with a well-designed GUI that "just works". General computing is important, it just shouldn't be the default option.

I propose appliance-default computers with a big red FTC mandated 'general computing' switch. It would save millions of hours in security and support costs, while protecting consumer freedom.

Anger and Frustration

It all started over Thanksgiving. Once again, it was time to answer family computer questions.

My father asked, "How can I be absolutely sure I don't get infected with CryptoLocker?". He was very concerned. It was on the news, and there was a warning email at work.

Unfortunately, there was nothing more I could tell him. He already does everything right, and could still be infected with CryptoLocker. There's nothing I can do: he has a computer and it can run malware. Sure there are precautions, but these are mostly useless.

Malware Precautions: Largely Useless

These (largely useless) precautions to avoid "being a victim" just happened to be on the news as I was drafting this blog post. The news report was about the recent social media password leak.

The precautions:

These precautions try to mask the core issue: malicious code can run on a computer, and there is nothing you can do about it except live in fear of every website and email attachment.

Even when following every single precaution, you could still be infected with malware.

Computers vs. Computing Appliances

The problem is that my father has a computer. A computer is a platform that permits arbitrary code execution. This encompasses pretty much all desktops and laptops.

What he needs is a computing appliance with a large monitor and a keyboard. A computing appliance is a platform that only permits execution of pre-approved code, like iOS or Windows on ARM.

In fact, the vast majority of people only need a computing appliance. They will never, ever develop software. They have no interest in running arbitrary, unapproved applications. The only unapproved code they will ever run is ZeuS or CryptoLocker.

A Computing Compromise

Every time OS vendors try to move into a direction of computing appliances, a vocal minority screams bloody murder. Just look at what happened when Microsoft introduced Secure Boot with Windows 8.

To some extent, these people have a point.

Computing appliances have many faults:

Of these, the last is the most important and can't easily be solved by competition between vendors.

It is important to let those who want to modify their computer and their software to do as they see fit. It just shouldn't be the default option.

The best execution of this I've heard of is the Developer Mode switch on Google's chromebooks. You have to physically flip a switch that allows unrestricted code execution. Additionally, flipping the switch wipes all local data.

It's a beautiful solution: there is no accidental enabling, and it prevents 'evil maid' attacks.

There is, of course, little profit in having a general computing mode in appliances. Most customers wouldn't use it, and it would cost time and effort to maintain. The only purpose would be to protect consumer freedoms.

Which is why computing appliances are a perfect target for government regulation. The FTC can require all computing appliances to ship with a 'general computing' switch to protect consumers from malware and controlling vendors. The millions of hours in saved frustration and tech support would be well worth it.