Tuesday, August 30, 2011

Kintera.org/Blackbaud.com infecting its users - on its donation page

I recently tried to donate money to a friend's charity. The page is hosted on Kintera.org, which includes a form to collect credit card info, and a Java applet that shows who else has donated recently. It uses a scrolling library they probably pulled off some untrustworthy website (I doubt it's the worse possibility - Kintera willfully infecting those making donations).

Unfortunately that scrolling library has 3 viruses, all of which act as Trojans to infect the user's machine and place them at the whim of a command and control bot network:

Java CVE-2008-5353.KM
Java CVE-2009-3867.GC
Java CVE-2008-3869.M

That's pretty embarrassing. The scroll page actually shows one page before you fill out your credit card info, so in the absolute worst case scenario, you view the page, click Continue while the infection is occurring, a keylogger downloads and runs, you enter your credit card info, and off it goes to as many as 3 bot network owners/users. Not cool.


Confidence indeed.

Monday, August 29, 2011

How to Root the HTC Evo Shift 4G

Sprint blocks their forums from viewing by non-logged-in users; this same information is posted at:
http://community.sprint.com/baw/message/329584

But you probably can't view it. Here it is reposted: How to root the HTC Evo Shift 4G.

You need the JDK installed:
http://www.oracle.com/technetwork/java/javase/downloads/java-se-jdk-7-download-432154.html

The Android SDK installed:
http://developer.android.com/sdk/index.html

And the HTC Sync software installed:
http://www.htc.com/www/help/ (scroll down to HTC Sync for all HTC Android phones and click Download)

Now follow these instructions:
http://forum.xda-developers.com/showthread.php?t=1185243

You'll need to cd into the directory where the Android SDK was installed, and then into the platform-tools directory inside that, in order to run adb and perform the other commands they ask you to run. You also need to move the 3 files they tell you to download into platform-tools (or, reference the path you downloaded them to in the commands you run - adb push).

This works on the current version as of this posting Aug 27, 2011: Android 2.3.3, but is unlikely to work in a future OTA update if there is one. Note that this only gives you temporary root but that's all you need to wipe out built-in apps you don't want. Note also that other temp root solutions like Visionary and permanent root solutions like ShiftRR will not work. Only the method linked to above will work on this latest OTA.

You can easily delete built-in apps while rooted by installing ES File Explorer from the Market (it's free), then go into Menu>Settings and check Root Explorer, then check Mount File System. Then browse to /system/app (you may need to change Home Directory to / instead of /sdcard to get to it). Press and hold on built-in apps you don't want, then tap Delete.

I deleted Amazon MP3, Nascar, NFL ("sfl-prod-release.apk"), Sprint Navigator, Sprint TV, and Swype (so I could install the latest). I doubt it's smart to get rid of the annoying Sprint Zone app because it appears to be how PRL updates etc get onto the phone.

You can prevent future OTA updates from putting all these apps back on by tapping Menu>Settings>Software Updates>HTC software update and uncheck Scheduled check. You can always explicitly ask for an OTA update if you want by coming back to this screen and tapping Check now.

Thursday, August 11, 2011

Stop Enforcement of Patents Without a Publicly Available Product


http://mobileopportunity.blogspot.com/2011/08/case-for-software-patents.html

He takes a long time to get to it, but I 100% agree:

restrict the right of "non-practicing entities" (patent trolls) to sue for patent infringement.

That's exactly what we need. Unfortunately he spends most of his time rehashing an old debate, briefly mentions this with no ideas on how to implement it (a tough problem), and moves on.

I think you could lay down some pretty simple rules. First, you could state that a patent cannot be enforced in court if what it protects is not available to the public either through your company or through a company that has licensed it. What this would lead to is a big company potentially stealing your idea while you develop it - but you can always finish the race to get it to market THEN sue for past damages. I think this is an acceptable outcome. It would prevent patent trolls from suing because they obviously have no intention of introducing a competing product, and the cost of doing so would be too high.

It would leave the licensing option open to some abuse though, and the definition of "available to the public" needs a tighter definition as well. But hey - it's a start. More than this guy tried.

He also leaves out one last negative impact of patents: They completely disclose to the world the details of what makes your product special. They protect you from the country against competition (and even then, probably only from small players in the country - big companies have a long history of kicking over the little guy, patents and all). I question whether the value of patents remains for small innovators (which should be the goal) when they have to fully disclose what they're patenting. It seems like you should be able to file a patent, get approved, but not have it go public until you give a say-so (basically when the product is released). There's no point in having the patent anyway until then (because you can't sue until it's available to the public), and making it known beforehand is dangerous - Chinese manufacturers love to just steal designs wholesale and give US companies the finger.

That's the final piece that's missing - worldwide protection after disclosure. That's really an enforcement problem. I suppose that's up to the PTO and the US as a whole to enforce - but only after we get our own **** together.

Friday, July 22, 2011

JQuery Utility Functions - grep()

JQuery's documentation can be a little light sometimes. Today we're looking at an underused core JQuery  function: $.grep()

First, the weird name. If you're not a Linux nerd, you should know that grep is a command in Linux that essentially searches, or more specifically, filters, stuff you pass to it. I would've preferred they call this command .filter() or .where(), but so be it.

As you've likely inferred, grep filters an array or collection of tags. It's like the WHERE clause from SQL or .Where(x => x...) in .NET's LINQ.

I'm going to send you straight to the fiddle for the code:

$.grep() example over an array

And of course, you can use it over a collection of tags - but the syntax is strange. For example, if you want to get a collection of input tags on the page where the user typed at least 10 characters:

var inputs = $.grep($('input[type=text]'), function(input) {
    return input.value.length > 9;
});

What's odd about this is it breaks convention with the rest of the JQuery collection methods. For example, you can set the text color to red for all tags selected with:

$('div').css('color', 'red');

So you would expect this to work:

$('div').grep(...

But it does not, even in the most recent version (as of this posting, 1.6.2). Instead you have to use .filter().

So now with the previous blog post on $.map(), we can get a little fancy. Suppose we've got a bunch of address objects from the server of the format:

var addresses = [
  {
    name: 'Brass Nine Design',
    address1: '321 Sesame St',
    city: 'Sesame',
    state: 'MA'
  }, ...
];

Suppose the user is going to enter a string, and you need to search names and addresses against it, then show the user the companies that match - listed by name. Remember that map is essentially SQL's select, and grep is essentially SQL's where. First you filter the list with grep, then extract the fields you wanted with map:

var matchingNames = $.map($.grep(addresses, function(addr) {
  return addr.name.indexOf(phrase) >= 0 || addr.address1.indexOf(phrase) >= 0;
}), function(addr) {
  return addr.name;
});

Voila.

Thursday, July 21, 2011

JQuery Utility Functions - $.map()

A lot of devs use JQuery nowadays without realizing how many little utilities are sitting inside of it. You can save yourself some coding time, and a fair number of bytes, if you understand what's underneath the hood. You might even get better performance given the optimizations that have been made to these core functions. Top of mind are:

.data()
.grep()
.map()
http://api.jquery.com/category/utilities/

You might begin by asking, "Why don't I just get rid of these? I don't use them." Unfortunately they're core to how JQuery works, so if you use a little bit of it, these are coming along. May as well learn them.

Let's do .map() today.

.map() is basically a translation function for collections. You pass in an array and a function, and the function is used to translate the array into another array. If you've used .NET's LINQ before, .map() is the .Select(x => x...) of Javascript.

As a simple example, suppose you have an array of objects you received from the server:

var people = [
  { name: 'Joe', city: 'Amherst', ... },
  { name: 'Sarah', city: ... },
  ...
];

Now suppose you wanted to just get a list of names in the data. The obvious way is to loop through it, either with for(var i = 0...), or if you want to get fancy, $.each(), but either way it's about the same number of bytes for the user. Here's the $.each() code:

var names = [];
$.each(people, function() {
  names.push(this.name);
});

And of course you'll end up with something that looks like
var names = ['Joe', 'Sarah', ...];

Let's see it in .map()!

var names = $.map(people, function(person) {
  return person.name;
});

And you end up with the same result. When this gets minified, it's easily the byte-winner. It's also likely that browsers will continue to offer more fast aggregation built-in functions - as they do, .map() is likely to adopt them, and you get performance gains for free.

Here's a JSFiddle with the 3 approaches, if you want to experiment:
http://jsfiddle.net/XdWVx/

In a sense, $.map() is $.each() for when you know you're building a new array from the thing you're looping through. As you might guess, you can use this on collections of tags. So for example if you wanted to rapidly gather the elements of a form into an array of values:

var values = $('input[type=text]').map(function(input) {
  return input.value;
});

It's important to notice a troublesome jQuery inconsistency here. $.each() iterating over a list calls back to a function that takes 2 arguments, the index of the array and the value at that index. $.map() calls back to a function with just the one argument, and no index - those who value consistency may writhe at this.

This inconsistency worsens when you loop over an object. In this case, $.map's callback now takes 2 arguments, the property name and its value - but they're reversed from their order used in $.each():

http://jsfiddle.net/b9chris/MGvp3/

Since a lot of legacy code likely depends on this lack of consistency in jQuery, the only clean answer is likely a small library that sits on top of it that rights the ship and cleans up the mess. Something tells me I'm not the first OCD developer to notice this - perhaps it's already out there. Links to libraries on github or other places that solve this problem are welcome in the comments.

Happy mapping.