Photo-1 Photo-2 Photo-3 Photo-4 Photo-5 Photo-6

@brentmc79

@brentmc79

Full-time web developer. Part-time smart ass.

I'm Brent Collier.

After a year and a half as an engineer on Twitter's Trust & Safety team, I'm looking for my next gig. Contact me if you know of something interesting.

#

TypeError: expected Array (got String) for param WTF

Posted on 10/17/2014

I was in the middle of completely overhauling some backend code, while attempting to reuse as much as possible of the semi-complex frontend. The form and js were basically the same, but I had to do some minor modifications to make it jive with the new ActiveRecord model that was backing it.

I had made what appeared to be the necessary changes, so why not give it a try? It's not like you can write tests for this stuff, right? RIGHT? I mean, it's javascript, client-side code, c'mon...

Anyway, I clicked the submit button on my form, expecting to watch the dev log for my incoming request, expecting to verify that my input params were correct, expecting to see something. But I didn't.

Blank terminal window

WTF?

In the browser there was a flash message with an error. That means there was definitely a request. But nothing in the dev log. How does that happen?

I checked the Network tab in the Chrome dev tools. There it was, a 500. Looking at the response, I could see the problem...

It had blown up in rack, not even making it to the Rails app. That explained why there was nothing in the dev log.

It was complaining about the source input, but what was the problem? I double-checked the input name...

<input name="source[]" type="text">

...made sure that it was the right format to return an array. It was. What the hell was going on? Finally, after searching through the view template, I realized the problem. There was another input - a hidden one, with the same name.

<input name="source" type="hidden">

That was it. Two inputs, both named "source". One a string, and the other an array. Fuck me.

I renamed one of the inputs, and BOOM, everything worked. Life goes on.

#

IP Address Regular Expressions

Posted on 09/26/2014

A regular expression for any ole ip address is pretty simple

\d{1,3}(?:\.\d{1,3}){3}

It basically just looks for 1-3 digits and (period, 1-3 digits) x 3. So that'll match 0.0.0.0 or 255.255.255.255 or whatever. The problem though, is it will also match 999.999.999.999 and last time I checked, that's not a valid ip address.

For single digits, number ranges are super simple in regular expressions...

  • \d is 0..9
  • [0-9] is also 0..9
  • [2-7] is 2, 3, 4, 5, 6, or 7

It's when you get into multi-digit number ranges that things get hairy. For our ip address regex, no digit group should exceed 255. Heres the regex to match 0..255

(?:25[0-5]|2[0-4]\d|1\d\d|\d\d|\d)

And here it is within the ip address regex

(?:25[0-5]|2[0-4]\d|1\d\d|\d\d|\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|\d\d|\d)){3}

That will match 0.0.0.0 up to 255.255.255.255, but not 255.255.255.256. What about zero-padded ip addresses? Well, first here's 000..255

(?:25[0-5]|2[0-4]\d|1\d\d|\d\d|0\d\d|\d|00\d)

And if we expand that into a fill ip address expression

(?:25[0-5]|2[0-4]\d|1\d\d|\d\d|0\d\d|\d|00\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|\d\d|0\d\d|\d|00\d)){3}

Depending on how you need to use the regular expression, it may be helpful to bound it to the beginning/end of the string

^(?:25[0-5]|2[0-4]\d|1\d\d|\d\d|0\d\d|\d|00\d)(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|\d\d|0\d\d|\d|00\d)){3}$

You can see it in action here.

Here's a few others to match typical private ip ranges

10.0.0.0 - 10.255.255.255

^10(?:\.(?:00\d|\d|0\d\d|\d\d|1\d\d|2[0-4]\d|25[0-5])){3}$

172.16.0.0 - 172.31.255.255

^172\.(?:\d|[1-2]\d|3[01])(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|\d\d|0\d\d|\d|00\d)){2}$

192.168.0.0 - 192.168.255.255

^192\.168(?:\.(?:25[0-5]|2[0-4]\d|1\d\d|\d\d|0\d\d|\d|00\d)){2}$
#

UndefinedConversionError can suck it

Posted on 09/04/2014

I have a bit of code in our app that downloads binary files and writes them to Tempfiles. Some testing led to the following exception:

An Encoding::UndefinedConversionError occurred in analyses#create:

  "\x90" from ASCII-8BIT to UTF-8
  app/models/analysis/malware.rb:193:in `get_file'

Line 193 looked basically like this:

tempfile = Tempfile.new('tmp')
begin
  tempfile.write(uploader.file.read)
ensure
  tempfile.close
end

I actually didn't want it converted to UTF-8, so a quick perusal of the Tempfile docs told me that I just needed to specify the encoding when I initialized the Tempfile.

So I changed the first line to:

tempfile = Tempfile.new('tmp', :encoding => 'ascii-8bit')

And everything was kosher.