I’m interested in checking out Go for a server I’d like to write eventually and was reading their FAQ this morning.

One phase stood out to me:

It would be nice to find a design that allows them to be truly exceptional without encouraging common errors to turn into special control flow that requires every programmer to compensate.

To me this is was astounding and almost revelatory. For years I’ve hated exceptions that create “flow” within the application. I couldn’t agree more that exceptions should be exceptional and subroutines that pass exceptions up tend to create massive catch sections that are nothing more than parsing exceptions from various subroutines. This can make sense in some instances of course but in many instances it defines the applications architecture. When using “ye olde” pen and paper programming approach, do you ever map out dozens of exception catches on a particular routine? While I have only limited experience in Java, I do fall back on it occasionally and have experienced plenty of instances where an exception dictates regular functionality in that language. A purist will say this is purposeful and useful. I agree that it is completely useful. However: with my background being mostly procedural I expect the function to return failure if necessary and not have both return values and as many exceptions it can throw as well. IMHO this leads to unnecessary complexity in writing the application but rarely adds significant usefulness.

I do agree that in a moderately sized OO application bubbling up exceptions makes complete sense if exceptions can be raised/thrown in subroutines. I just don’t necessarily agree that it’s a good idea that increases programmer productivity for a language to do that. In my (humble / uninformed) opinion, languages should help with productivity and help you get the most out of your day. My experience says exceptions and exception bubbling decreases my productivity because I have to implicitly check for exceptions rather than just returns from methods and functions. Or in a worst case, I can’t just check for failure, but rather multiple different failures as well as returns. I’m not an expert in in this matter, just one of those that writes a lot of code in various languages on a daily basis. If Go is useful to me I’ll probably start using it regardless of whether I’m mistaken by their assertion, their FAQ just kinda sucker punched me into writing about exceptions.

</rant>

Regardless, check out Go. Initially it looks like the syntax may be a little different from what you’re used to however it seems well thought out.

Due to the inherent ambiguities in form-based logins, there’s an unavoidable tradeoff here between making the password manager work on lots of sites, and having it match the behavior of the old FF2 password manager (which checked field names). We’ve chosen to go with better functionality in the new password manager.

From: https://bugzilla.mozilla.org/show_bug.cgi?id=499223

This is kinda funny actually.   The vast majority of sites field names for username and password do not change, or only change when there is a redesign.   This thought process assumes that sites might *constantly* switch field names or form names or other basic tag attributes to confuse just who now?

Love Firefox but this decision (RESOLVED WONTFIX) irks me.   Now I’ll have to turn autocomplete off on any plain text field followed by a password type field just to cater to Firefox’s overzealous credential remembering scheme.

Need to file a new feature request:  Please let FF3 alert me when it’s using stored credentials (infobar type thing maybe) because maybe the user can’t see   the field that’s now submitting my username and password to the world.

On another note, this seems like an easy way to gain login credentials of people using sites that allow for code import / widget creation, ugh.

A word to the wise:  don’t allow Firefox to store your usernames and passwords.  This “feature” is incredibly ill conceived and can result in your username and password for various sites being exposed.  Frankly unless you’re careful, it will result in this depending on the sites you use.

We’ve been struggling with this on one of our sites for some time, believing (incorrectly) that our code was defaulting the username and password into certain incorrect fields.  After doing a thorough review we learned that the behavior was only happening to Firefox users (3.0+ specifically for us, but had no 2.0 users to validate against).  Turns out their implementation of cached usernames and passwords is craptastic at best, negligent at worst.  Firefox “remembers” your username and password and then attempts to store it into *every* page that has a “password” type input field that is preceeded by a plain “text” type input field.  This means that if a website you visit happens to have multiple fields (for whatever reason) that are of the type “password” Firefox will store your password in it and your username in the field before it (if you are allowing usernames and passwords to be remembered by firefox.)

Here’s a bug report over at bugzilla:  https://bugzilla.mozilla.org/show_bug.cgi?id=496838

This bug has been around awhile, but for us only recently reared it’s ugly head.

Why this sucks in the real world:  One of our products has an Account Number field that we use to allow the user to store some information that they might want to shield from prying eyes / neighbors.  As such it’s of the type “password”.   This field is not required and exists on a secondary html element “tab”.   Firefox’s stored password “feature” could have caused serious exposure of people’s usernames and passwords had we not been alerted to it and advised users of what was going on.  Now we’re faced with a dilemma, code to “blank out” these fields when it’s indeed empty and Firefox has stored info in it, use “autocomplete=off” attribute on those fields (even though it’s super handy to auto complete those fields in other browsers), or switch to  plain text fields.

We *love* Firefox, so much so that we push it on our users at every turn to help them be more productive and, most importantly, more secure.  This terrible implementation is a perfect example of how developers can overlook a simple feature while implementing better security and leave their users completely exposed.

Remember though, for whatever it’s flaws, it’s still quite great compared to IE.

One of our business partners picked up this book at the door64 tech fair in Austin recently and tossed it off to me.

I wanted to mention that I thoroughly enjoyed the book.  An easy read (I started and finished it while watching some TV Monday night), the main focus is on lightweight code reviews.  For those of us in small development shops it can be hard to justify to management why time on code reviews (personal or peer based) needs to be spent and how it directly saves money for the business. When it comes to books on peer code review there just aren’t that many so I was psyched when this dropped in my lap but a little hesitant as it looked to be basically adware.  Luckily I proven wrong.

I’d recommend this short primer to anyone who is struggling with the “code -> test -> deploy” process practiced at a lot of development shops or wants to justify to management the need for peer (or personal) code reviews.  When dealing with management it’s often difficult to justify why programmers want to follow process X or process Y and this book is lightweight enough to pass onto any layman.

Above all the best section in this book, for me, deals with how to conduct a personal code review.  In a smaller development shop you may be the only one to work on a single product or in a particular language or focus.  (For instance in many past ventures I have been the only developer for various products.)  This can be a severe disadvantage at times, for while the lone developer has almost complete leeway,  they do not always know “is this right” or even “is this going to work.”  When coding solo, my process was to to code, personally test, send to testing peeps (if available), patch if necessary and publish.  This has sucked beyond all measure at times due to bugs getting to customers and past testing.   Occasionally you just need someone to give you a push in the right direction and in my case this book shoved me towards individual checklists to run through when reviewing your own code as well as helping establish the proper amount of time to set aside to do a thorough personal review.  While that may sound minor, sometimes even the most minor thing can help push you in a better direction.   If formalizing the personal review process helps you catch even 10% more bugs that would be customer facing, then this book was a worthwhile read.  Beyond that, keeping a checklist of personal common mistakes and ensuring that you aren’t continually making them will make you a better programmer.

A few caveats:  the book isn’t a “how to conduct peer code reviews” however it does arm you with enough knowledge that you can track down the process that would work for your team.  They also promote their review software “Code Collaborator” a lot, however that’s ok, everyone has to make a living.

The only drawback (unless you’re one of those that hate advertising in any degree) is that this book is a bit too lightweight.  I hope that at some point Cohen expands on the concept with a lot more details, in depth case studies, real world examples and general content.    At that point I would probably take this from the “personal reading” stack and shuffle it over to required reading.

Update:  Click the image above to order from Amazon or click here to get a free copy from SmartBear

Posing

More Here

Any suggestions on a name?

Update:  His name is now Cosmo (or Cozmo, unsure which :D )

I’ve been asked a couple of times about how to track an adobe AIR application you’ve developed without disclosing personal information or requiring user interaction.

My answer to this is always the same: I usually store a randomly generated key in the SQLite database when the application is first run.

I’ve decided to upload some code to demonstrate *my* approach to synchronous database connections in Adobe AIR.  The version of the code provided is a bit stripped down from what I usually use (my main code provides for both synchronous and asynchronous connectivity but I stripped a lot out for this example and will provide a seperate example for asynch at some point int he future.)

To reiterate: This code may be overkill for some people and uses my custom namespaces.

Now that I’ve got that out of the way:

Download: SQLiteExample.air OR SQLiteExample.zip
License: Creative Commons Attribution 3.0 United States License (Please keep or attribute name in code comments etc.)

Quick and dirty explanation:
Since this is a lightweight application I use my trusty airDB javascript namespace.  airDB is just a wrapper I wrote to simplify synchronous SQLite connections to the air database.    Three main methods are really all you need to understand to get started  (see code as well method list below).  Those are airDB.init(), airDB.fetchRS and airDB.execute.  If you’re just looking for an explanation of how to connect / work with a SQLite database in AIR read the documentation here or check out my source file ns.airDB.js (I’ve heavily commented it hopefully to help explain things but frankly I’m bad at that so the official Adobe help is probably the way to go).

Within the startup method in the index.html file you’ll find that I’m calling airDB.init with an object passed in.

// initiate db connection / test schema etc
// see init in ns.airDB.js for more information
airDB.init({
databaseName: 'example.db', // name of our database
fetchJSArray: 1, // force fetchRS to return a javascript array
openImmediately: 1, // open the database on init
testSchema: 1, // test the database on init
traceLog: 1 // verbose log to air.trace
});

A little information about ns.airDB.js:

  • airDB.init (options)
    • performs initial setup of connection variables needed to access the SQLite database in synchronous modeSee the init method for default options and their use
    • Returns:  null
  • airDB.open()
    • opens the database connection.  Requires that airDB.init has specified a filename to connect to
    • [Optional]; can be called directly from init if openImmediately is passed in as 1.
    • Returns: null
  • airDB.close()
    • closes the database connection
    • Returns: null
  • airDB.test(forceFail)
    • performs a basic schema test to see if the database is setup.  (set forceFail = true to recreate the database regardless of test results).
    • Note:  This method should be rewritten to each specific application as schema will vary per application.  The provided one is super simple for examples sake.
    • [Optional]: can be called directly from init if testSchema is passed in as 1.
    • Returns: null
  • airDB.connected
    • Returns: boolean (whether connection is present or not)
  • airDB.fetchRS(sqlStatement)
    • performs a SQL Select statement or other statement that is expected to return a recordset.If fetchJSArray (in init) is = 1, we return a custom javascript object that’s formatted like the following:
      {
      rows: number of rows returned,
      data:   array( row 1 =>  {columnName1: columnValue1, ColumnName2, ColumnValue2}   )
      }
      (using this type in the example code)

      if fetchJSArray (in init) is = 0, we return a flash.data object (More information on handling that return type can be found here)

    • Returns: Javascript Object or Flash.Data object dependent on init option “fetchJSArray”
  • airDB.execute(sqlStatement)
    • executes a sql statement (insert / update / delete / drop etc.)
    • Returns: null
  • airDB.sqlText(string)
    • replaces any single quotes in a string with double quotes
    • Returns: string
  • airDB.sqlNumber(number)
    • ensures that a number passed in is numeric / ok to execute in a sql statement
    • Returns: number (returns 0 if number is not numeric)

After init in the “startup” function I call airKey.init  airKey is a javascript namespace solely created for generating a random string of however many characters you wish and storing that in the local database.  I won’t go into too much detail here because it’s super easy to understand (generate a key if one isn’t present and store it in the database, if one is already present, retrieve it.)  (see ns.airKey.js)

I then call a custom function called “getNames()”.  getNames is just an example of how to call a select statement and use the custom JS array to output data.  In the example provided I fetch the column names as well as the values to generate the table of “names” within the main air window.   When looking at the function you might ask why  I’m using a custom javascript recorset that fetchRS returns rather than the standard flash.data object.   1 :  my custom object returns the number of rows as a static int,  so that I never have to calculate that.  2 : I also don’t want to pass flash objects around because it’s caused memory leaks for me in the past that were a pain.  (However if that’s your thing, remember you can just set fetchJSArray = 0 (or not pass in that option at all) in init to just use standard access methods.  (I do this for large databases because transforming the data on large recordsets is a bad idea)

Other than that, this example is pretty basic.  Adding a name using airDB.execute as well as rebuilding the database from scratch is included in the example.

Finally:  a bit more about airKey.  by storing a random string I can test against that when the application performs URLRequests against an owned web service.  This lets me generate reports (or turn off a particular app) without having to be too intrusive to the user.  To make this more robust I highly recommend using the local Encrypted Store available to you in AIR applications.  (If you’re worried about piracy of your application the encrypted store will help a little but frankly right now AIR is not the platform (for HTML/JS applications) to use if  that’s your concern as source code is freely available to the user.)

If you have any questions feel free to ask in the comments and I’ll answer.

Posting to give an example of how to print using the local browser using Adobe AIR.  This is in response to this AIR forum thread.

I need to have an alternate stylesheet for my application so I embed those styles in an inline style tag from a css file.  I also do not want to include all the scripts and external references that my application may have on the particular page so I strip out only the body and build a new page from it.

This probably isn’t for everyone but might give you a good idea of where to start (or provide an example of how not to do this).

Note this uses jQuery’s .html function, but you could just as easily replace that with document.getElementById(‘MyPrintableStuff’).innerHTML();

 

/*
    Quick and dirty print function for AIR
    @htmlTitle string    :    text to be placed in <title> tag of the document
    @printCSSFile    :    css file to parse, should be relative to the app ie 'stylesheets/print.css'
*/
function printThis(htmlTitle, printCSSFile)
{
    var locFileStream = false,
        styleFile = air.File.applicationDirectory;
        locStyles = '';

    /* fetch css definitions for print stylesheet and store in locStyles */
    styleFile = styleFile.resolvePath(printCSSFile);

    locFileStream = new air.FileStream();
    locFileStream.open(styleFile, air.FileMode.READ);
    locStyles = locFileStream.readUTFBytes(locFileStream.bytesAvailable);
    locFileStream.close();

    /* HTML to string */
    locHTML = $('body').html();

    /* wrap with doc tags, add "window.print" to the onload */
    locHTML = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">' +
            '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">' +
            '<head>' +
            '<title>' + htmlTitle + '</title>' +
            '<style type="text/css">' +
            locStyles +
            '</style>' +
            '</head>' +
            '<body onload="window.print()">' +
                locHTML +
            '</body>' +
            '</html>';

    /* output the file to a temporary file in user's docs, launch url in native browser
        TODO: delete tmp file after launch
    */
    var tmpFile = air.File.documentsDirectory;
    tmpFile = tmpFile.resolvePath("temp.html");
    tmpURLToOpen = tmpFile.url;

    var tmpFileStream = new air.FileStream();
    tmpFileStream.open(tmpFile, air.FileMode.WRITE);
    tmpFileStream.writeUTFBytes(locHTML);
    tmpFileStream.close();

    var locURLReq = new air.URLRequest(tmpURLToOpen);
    air.navigateToURL(locURLReq);

    /* null objects */
    locURLReq = null;
    tmpFileStream = null;
    locFileStream = null;
    styleFile = null;
}

http://www.americanprogress.org/issues/2009/03/progressive_quiz.html

I got 325/400 or “Extremely Progressive”.

The mean of people who identify as “Liberal Democrats” was 247.1 so maybe I’m secretly Canadian.

Lots of people (1,2 and many others) are trumpeting the idea that Adobe AIR is somehow not secure when compared to other deployable applications.  I think it’s time we laid this one to rest.  Adobe has done absolutely nothing to assure end users and in fact, by their ridiculous “badge” installer warnings, they have made this worse.

Nothing that you download and install on your computer can be considered “Secure”. If a user installs a program they are providing a level of trust to that application.  If anything, Adobe is providing a level of warning above and beyond that of a typical .Net or java executeable.  (At least it’s a requirement that AIR applications be signed to be deployable).

Lets compare a .NET executable on your system vs an Adobe AIR executable (windows used as an example).

.Net (VB / C# etc)

  • Warnings on “security” within the installer — Little to none depending on installer used
  • Must use a certificate — No (Of course it can and should)
  • Has Registry access — Yes
  • Can silently install other applications — Yes
  • Can silently install BHOs and malicious software — Yes
  • Can add itself to startup — Yes
  • Can monitor network activity — Yes
  • Can sniff network activity — Yes
  • Can affect device drivers — Yes
  • Has complete system access — Yes (If running from an Admin user)

Adobe AIR

  • Warnings on “security” within the installer — Ridiculous over the top warnings are the norm
  • Must use a certificate — Yes (Self Signed certs are avail, but will display as “Unknown” publisher)
  • Has Registry access — No (Not without significant hacks like the Java bridge)
  • Can silently install other applications — No (It can’t even install other AIR apps w/o user interaction)
  • Can silently install BHOs and malicious software — No (AIR in theory could deploy into a directory but could not load into the reg)
  • Can add itself to startup — Yes (However, startup appears in user’s “Startup” Program Files menu)
  • Can monitor network activity — Yes (included class only monitors whether connection is present or not)
  • Can sniff network activity — No
  • Can affect device drivers — No
  • Has complete system access — No (However like almost all executeables it has access to the same areas of the filesystem that the “run as” user has)

RIA platforms are no more “dangerous” than any other platform.   In fact Adobe has gone above and beyond (in my opinion hampering creativity and developer happiness) to ensure that AIR applications are at least crippled when it comes to their ability to deploy malicious payloads.

I do believe AIR could be used as a bit of a trojan to deliver malicious exe’s that are bundled in the AIR installer file.  That said, that’s hardly a “security” flaw w/ AIR as that same “flaw” is built into the nature of software packaging.

Fear… Uncertaintainty… Doubt, thy name is Adobe AIR.

http://www.salon.com/opinion/greenwald/2009/02/22/militias/

And I wonder what would happen if MSNBC broadcast a similar discussion of leftists plotting and planning the imminent, violent Socialist Revolution against the U.S. Government.

 

January 2012
M T W T F S S
« Nov    
 1
2345678
9101112131415
16171819202122
23242526272829
3031  
Follow

Get every new post delivered to your Inbox.