Sunday, October 21, 2007

Moving Blog

I'm moving the blog to http://blog.battlebazaar.net

Wednesday, April 11, 2007

DataBinding to RowError in a DataTable

In ASP.NET, sometimes we need to bind to the RowError from an ADO.NET DataSet. You might do this to support partial committed updates, for example, and report errors on records that did not work.

<asp:label id="RowError" text="'<%# GetDataItem().Row.RowError %>" runat="server">'></asp:label>

We have to do it this way because DataRow and DataRowView have special logic. In particular, references to them are resolved to their collection of items, and not to the DataRow or DataRowView itself. This is so you can have a column named RowError, which albeit stupid if you're using ASP.NET, could actually happen in the real world.

So what we do is GetDataItem (the syntax shown is VB.NET -- but should be easily adapted to C#, Chrome, Python, Lisp, Fortran, Cobal or whtever you are actually using). That returns the DataRow / DataRowView itself. Since I use a DV, I get a DataRowView, and have to go up to the real row (the Row property). Then, I pull the RowError property.

The point is understanding why something is wrong, and what tools you hae to fix it. Bind expressions are translated into calls to DataBinder. GetDataItem returns the item being used for binding data, so that you can access any arbitrary property. Otherwise, the object can (through various mechanisms) override DataBinding to make it "easier" on users of the class.

Monday, February 26, 2007

URI Parsing in IE7

Of course, what's needed here is a new class in Internet Explorer, for Internet Explorer to parse URI's. That makes so much more sense than simply compiling Internet Explorer with Managed C++ and using the existing System.Uri class that performs this same task in .NET code, and has handled IP v6 addresses for some time. More redundant API's is exactly what everyone wants in Windows.

Tuesday, February 13, 2007

JSON vs XML

I see a lot of people moving to JSON to save space in requests; sometimes at a cost of security, so I asked myself what makes an XML request so large. Usually, they are arguing that JSON is smaller, and easier to process. They make this assertion by showing element-based XML. This has an begin tag and an end tag for each field, so it looks like this:
<data>
<table1>
<col1>value1</col1>
</table1>
</data>
They say this is the equivalent JSON: ({ "data" : { "table1" : { "col1": "value1"; } } }) Now the problem is that JavaScript isn't equivalent to the XML shown, instead it is equivalent to this XML: <data> <table1 col1="value1"> </data> The original XML has an object for col1, which serves as an extension point. In this case, clearly, no extension point is required and there is no advantage to having col1 as a child element versus having it as an attribute. If you use attribute-based XML, the resultant data is often smaller -- not larger -- than the JSON equivalent, and it is perfectly valid to use attribute based XML. For example, if you look at an HTML document: <div id="'123456'" name="'someName'"></div> A div is a container, so it must be an element. The properties of the element are listed inline, as attributes. They don't serve as extension points, and they aren't containers, so they are attributes (and not subelements). That is the same approach that should be taken in XML. Unless the data is either an extension point or a container, then it should be an attribute, not an element. HTML, XHTML, WordML, and ExcelML all provide examples of how to accomplish this. Conversely, object is an extension point -- with object, you have parameters which themselves might be markup fragments: <obeject class='blah'> <param name='param1'></param> </object> Here, you need the extension point. The issue with comparing JSON to element based XML is that element based XML ought to be the exception, not the rule. When you compare JSON and attribute based XML, what you find is that at about 20-30 records of data, the attribute based XML becomes smaller -- not larger -- than the JSON. At about 100 to 1000 records of data, the attribute-based XML is substantially smaller. There are contrived test cases that can counter this for specific data sets; the way I make this determination is simple. I have a "Ajax" HTTP Handler in .NET, and when I make a URL for a script block, I tell it whether I want that particular wrapper to be JSON, Element XML or Attribute XML. And it then does the rest. During testing phases of a web application, I try all the settings while using a proxy such as Fiddler that can tell you what the request sizes are looking like, and I simply look where for common use cases it is better. The other concern about JSON is the use of eval -- injection attacks are possible against eval from mixed data sources, even when getting the data from a known secure server. Eval, among other things, decodes HTML entities, and if you aren't alert for that, you can easily break out of the eval and manipulate the page. What people are less knowledgable about is that JSON that breaks out this way isn't limited to just communicating with the hosting server. No browser limits Image, IFrame, CSS, and other HTML elements in any way. You can create a form in a hidden IFrame (for example), point it towards any arbitrary web server, and do a submit, and only the invisible IFrame will update! Yes, I have a problem with using eval for anything that might come from any database. I think it is just begging for problems. You add a JSON parser in there, and anything you might have gained in per-request size is lost.

nVidia Saga comes to a close

OK, So I'm working on repairing another XP CD, and I go to VIA's website for drivers. This mainboard is 5 maybe 6 years old, oh and by the way a discontinued chipset. How long do you think it took me to find a driver pack that works with all versions of Windows, including Vista? 5 minutes. Thats right -- VIA has a universal driver pack, it works with their legacy boards, it works with their new boards. This just further infuriates me -- nVidia is advertising -- heavily -- how great their products are for Vista, and then they are doing precisely nothing on their "legacy" products -- keeping in mind they've only been making chipsets since 2004. And their video hardware, its starting to go the same way. Take a look at their site, there is a "Unviersal Driver" for all nVidia cards, and then there is a separate driver only for the 8800 series. That is, specifically, so they can drop support for the older cards going forward -- many of which are still being sold in stores today, based on nVidia's reputation.

Sunday, February 04, 2007

Vista, nForce 3 and never another nVidia product -- ever

OK, So after a few days of fighting Vista's installer, I go to control panel, remove all the optional windows features (you heard me -- all the built in stuff, IIS, Unix Services -- all of it), turn off proxy (trying to upgrade the machine that I use for the proxy on my home network), and finally get it to install. After messing with it for a while, I reboot and I receive: Unable to load pxhelp20.sys Please boot off the DVD. So I try it, and it doesn't work. Then I try again, and it still doesn't work. And again, and nothing. And so forth. I try loading the XP drivers, then I start looking around. This board was produced under two years ago, using nForce 3 hardware. I obtained it under a year ago, as a replacement when my old board died. I went nForce 3 because I needed an AGP mainboard, because I didn't have the money (at the time) to replace the video card and other system components -- I just needed to get the computer back up and running. The issue is, nVidia has decided not to update the device drivers for this mainboard anymore. They've posted so publicly in a couple places, and said they consider it to be 'obsolete.' What I find funny about this is the Adaptec SCSI controller I bought more than ten years ago continues to function and drive my CD Writer and DVD RAM; it does so with current, certified drivers. Adaptec has newer models, sure, and the drivers support those new models also, however... The controller is just talking to the hard drive. The SATA is sending serial messages to a hard drive, receiving serial data back, and spooling that data into memory. It isn't like it is some technological marvel -- certainly, there shouldn't be any significant changes that need to happen to the controller to CPU interface. Sure, there might be new instructions you can send to newer drives, or newer, faster speeds, but the mechanics shouldn't be different enough to require new drivers. My Adaptec controller talks to SCSI-LVD drives; the one before it (same driver) talks to SCSI-2 drives; the one before it (same driver) talks to SCSI-1 drives, and the one before it (same driver) talks to SCSI-1 drives. The driver simply determines what chip it is talking to, and then limits its command set and features to what that chip understands. On SATA and SCSI drives, the drive itself has intelligence -- the chip should be doing very little other than passing a command (go to this spot, read n sectors of data, and send them back to me). Anyway, Logitech's BlueTooth hub is on my replace list, as is my Lexmark Z82 and as is my motherboard. The motherboard was already on the list, but now its moving up. I'll probably go with a BT v2 hub, and just stick with the cordless MX desktop for BlueTooth -- I love the keyboard and mouse, I just can't stand Logitech's bluetooth drivers.

Tuesday, August 08, 2006

Printing and IE 7

Ease the pain with IE 6 printing A couple people in here mention text areas. For text areas, my suggestion is using JavaScript to convert them to div's before printing, and then convert them back to TextArea afterwards. This involves capturing the print some how, the most obvious way being to provide a button or link with an onclick event. You can't do this with CSS alone, because FireFox and Internet Explorer both have significant issues with printing any text area. Neither, however, has any problems printing text in a div. The margin on the right thing is a result of using the combination of "standards mode," CSS2 and percent widths. That combination makes Internet Explorer fail computations. If you use an outer element, and then size and position based on it, it fixes it.

.NET Work Around

We ran into a problem with no-touch and URL's that look like this: https://someServer/someProgram.exe?parm1=val&parm2=val&parm3=val&data=https://someServer/dataService.asmx The problem is that .NET 1.1 on a URL wildcard correctly parses the URL and applies CAS rules attached to https://someServer/someProgram.exe. .NET 2.0, on the other attempted to match the data URL at the end. The result is nothing we did could get policy to apply to .NET 2.0. To work around this, I wrote a launcher DLL. All it does is use AppDomain.ExecuteAssembly. I construct a new AppDomain, I use ExecuteAssembly, and I'm done. I embed the launcher control on the page (using an object tag) in place of the HREF. To work around the EOLAS patent, I use a JavaScript to render the actual object tag. No big deal at all. This technique works on Internet Explorer and on FireFox with the .NET handler plug in. It has an added bonus that you can know what version of .NET is installed before loading the assembly, and so your launcher can switch based on that information.

Friday, July 07, 2006

Registry and NetRefactor

I previously was recommending NetRefactor as a refactoring tool; however, their developers were writing files to my Program File directory. When I upgraded Windows, the setup program tagged my Program Files directory as "Deny Write" for everyone, and hung a specific "Allow Write" for Administrators. I liked this change, as well as a similar change to the Windows directory and the root of the boot partitions, and so I retained the change. Now NetRefactor tells me it's a "catch 22," they have to write their configuration data to Program Files (where you haven't been supposed to store configuration data since Windows 3.0), because they can't write to the registry in a corporate environment. Their only two choices are to put the configuration in program files, or put the data in the registry. It isn't a "catch 22." First, there are several registry hives. User settings are written to HKEY_CURRENT_USER\Software\Vendor\Application. This hive is not locked down in any configuration, and will be writable. It is the standard place to store small amounts of configuration data. But Microsoft recommends not using the registry to store configuration data if there are more than a couple keys. What you want to do is store configuration in the "Application Data" folder. You get this path via System.Environment. There are two of them, one for "all users" (common) and one for the current user. You want to write configuration data for the current user. For users with roaming profiles, there is an option to save the configuration locally or roaming (you can ask for either path). For their benefit, you want to use the roaming profile, so when they go to another PC, your settings follow them just like every other application's settings. The whole point here is it is a "catch 22" only if you aren't following the Windows Application Guidelines as they have existed since Windows 3.0. Yes, if you give Microsoft the middle finger and do whatever you want in terms of where you write the software, you work fine on an unsecured system running on a FAT file system. The issue is that is not the world today anymore, and tomorrow the configurations are getting only tighter. You have to do the right thing and follow the guidelines. If you use the Windows Profile API's (*PrivateProfile* in PlatformSDK), those files are stored in the correct place. If you use HKEY_CURRENT_USER\Software (and not HKEY_LOCAL_MACHINE), it isn't locked down in a corporate environment. When you use Application Data, or My Documents even (as Visual Studio itself does), you run on a locked down environment. It is when you do not follow the guidelines that you get burnt, and it is applications not following the guidelines that are causing most -- if not all -- of the security problems. Now normally having to go to the program files directory and set an ACL to allow a couple files to be written isn't a big deal, however the response I got was "we can't do this because it isn't possible." They can't follow established windows guidelines that I have to follow every day, to load my software on computers that are locked down at very security concious sites, because it isn't possible -- even as the application they are running in does the right thing, and works in that same environment. And again, even that usually wouldn't be enough to do it, but NetRefactor isn't working correctly -- even with full Administrative rights and full permissions on the program files -- on anything in VS 2005. Basic refactors like "extract property" are failing, while Refactor! and the built in Visual-Studio refactorings are working correctly on the same code. I suggest getting off of NetRefactor as soon as possible. It seems Refactor! works, and so my suggestions would be to move to it.

Tuesday, June 20, 2006

HOWTO: Simulate "keep together" in IE

I will do a version that works in FireFox later on, this version works only with IE 6 and 7. This simulates the "keep these lines together" or "keep this block on the same page" style options in a word processor. CSS doesn't offer a standard way of marking an element to be "kept together" when printed. The best you can do is ask for a page break before or after a specific element. The JavaScript looks like this:
function test()
{
 var blocks = document.all["content"].childNodes;
 var currentPage = document.createElement("div");
 currentPage.className = "page";
 document.all.pages.appendChild(currentPage);
 
 var content = document.all["content"];
 
 while (content.childNodes.length > 0)
 {
   var block = content.childNodes[0];
   currentPage.appendChild(block);
  
  var pageTop = currentPage.offsetTop;
  var pageBottom = pageTop + currentPage.offsetHeight;
  var blockTop = block.offsetTop + pageTop;
  var blockBottom = blockTop + block.offsetHeight;
  
  block.blockTop = blockTop;
  block.blockBottom = blockBottom;
  currentPage.pageTop = pageTop;
  currentPage.pageBottom = pageBottom;
  currentPage.pageHeight = currentPage.offsetHeight;
  
  if (blockBottom >= pageBottom)
  {
   currentPage = document.createElement("div");
   currentPage.className = "page";
   document.all.pages.appendChild(currentPage);
   currentPage.appendChild(block);
   block.className = block.className + " newpage";
  }
  }
 }
 
 test();
This is very IE specific right now, and I appologize for that if you are a FireFox user. As I said, I'll work up a more generic one later on. The script takes block level elements from the "content" div and moves them one at a time into a new "page" div. The page div is formatted like this for screen: .page { height: 11in; width: 8.5in; border: 2px solid black; display: inline-block; overflow: hidden; padding: .5in; page-break-after: auto; } For print media, the following rule is added as well: @media print { .page { border: none; padding: 0px; } } For debugging purposes, I add the "newpage" class to the first block on each page -- this could as easily do other things. I also stash some values that I can view with the IE Developer Toolbar for debugging purposes.

Thursday, May 04, 2006

Printing from CSS

Stylesheet Examples This site has some very useful information. It also has some very wrong information, so take anything said there with a grain of salt. In particular, print templates (something it talks about) are a technique for applications such as Outlook to capture and modify how Internet Explorer prints. I've used them, successfully, and there are a great many other people who have used them successfully. The technique is used with the Internet Explorer control, which can be embedded in an application. The Internet Explorer control is not the same as the Internet Explorer window -- and you cannot (I repeat cannot) use this technology from a web page. There are some political comments on using tables for form layout. I still suggest using tables for form layout; there are two large issues here. A browser that does not understand fieldset and that does not understand CSS will render a fieldset as plain text. It will process any HTML inside. So on those browsers, you will get an extremely un-user friendly form. For most applications, the audience drives the application and the profit. If you have a manage running IE 5.5 mac on office machine, then you make sure that your page renders in IE 5.5 mac, you have no choice. If you are writing a storefront for a product or service, you cannot mandate the use of a standards compliant browser without losing sales. I agree with most of the rational about using CSS to drive presentation, and don't get me wrong, I am in no way saying 'give standards compliance the middle finger.' What I am saying is that you have to consider your audience, their experience and their patience. In the early 90's, you had mostly highly technical people on the web. At the time, it was perfectly feasible and viable to say 'This page requires browser A or browser B at 800x600 and blah blah blah'. It was viable because the only people who were viewing your site or using your application were the handful of people on internet, and most of those were highly technical and technological people. Now, in the 2000's, we have a large number of largely uneducated users who can barely log in to their computer, and keep their ATM PIN written on the back of their card. Unless you are writing a highly technical site, you have to keep your site simple and direct. As soon as you make the site complicated, unfriendly, or require installation of Gecko/FireFox, you've got a problem.

Monday, April 24, 2006

.NET Development

How to accept (or at least report) invalid certificates in .NET This is step by step instructions. The result of following them resulted in the following class for me:

  Class CertPolicy

    Implements ICertificatePolicy

 

    Const CertVALIDITYPERIODNESTING As Long = 2148204802

    Const CertROLE As Long = 2148204803

    Const CertPATHLENCONST As Long = 2148204804

    Const CertCRITICAL As Long = 2148204805

    Const CertPURPOSE As Long = 2148204806

    Const CertISSUERCHAINING As Long = 2148204807

    Const CertMALFORMED As Long = 2148204808

    Const CertCHAINING As Long = 2148204810

    Const CertREVOKED As Long = 2148204812

    Const CertUNTRUSTEDTESTROOT As Long = 2148204813

    Const CertREVOCATION_FAILURE As Long = 2148204814

    Const CertWRONG_USAGE As Long = 2148204816

    Const CertUNTRUSTEDCA As Long = 2148204818

    Const CertCN_NO_MATCH As Long = 2148204815

    Const CertEXPIRED As Long = 2148204801

    Const CertUNTRUSTEDROOT As Long = 2148204809

 

    Private m_FT As FilteredTable

 

    Public Sub New(ByVal FT As FilteredTable)

      m_FT = FT

    End Sub

 

    Public Sub New()

 

    End Sub

 

    Private m_AllowExpired As Boolean = True

    Private m_AllowUntrustedCA As Boolean = False

    Private m_AllowBadName As Boolean = False

 

    Public Property AllowUntrustedCA() As Boolean

      Get

        Return m_AllowUntrustedCA

      End Get

      Set(ByVal Value As Boolean)

        m_AllowUntrustedCA = Value

      End Set

    End Property

 

    Public Property AllowBadName() As Boolean

      Get

        Return m_AllowBadName

      End Get

      Set(ByVal Value As Boolean)

        m_AllowBadName = Value

      End Set

    End Property

 

    Public Property AllowExpired() As Boolean

      Get

        Return m_AllowExpired

      End Get

      Set(ByVal Value As Boolean)

        m_AllowExpired = True

      End Set

    End Property

 

    Public Function CheckValidationResult(ByVal srvPoint As System.Net.ServicePoint, ByVal certificate As System.Security.Cryptography.X509Certificates.X509Certificate, ByVal request As System.Net.WebRequest, ByVal certificateProblem As Integer) As Boolean Implements System.Net.ICertificatePolicy.CheckValidationResult

      ' you can do your own certificate checking here

      ' you can get the error values from WinError.h, all the certificate errors start with Cert_

      ' we just return true so any certificate will work with this sample

      Dim probLong As Long = CLng(certificateProblem)

 

      Select Case probLong

        Case CertEXPIRED

          m_FT._ErrorMessage = " Cert is in invalid time"

          Return AllowExpired

        Case CertUNTRUSTEDCA

          m_FT._ErrorMessage = "The CA is not trusted"

          Return AllowUntrustedCA

        Case CertUNTRUSTEDROOT

          m_FT._ErrorMessage = "The certificate name is not match"

          Return AllowBadName

        Case 0

          Return True

        Case Else

          m_FT._ErrorMessage = "Server Certificate has a problem (SSPI Code is " & certificateProblem & ")"

          Return False

      End Select

    End Function

  End Class

 

This class allows certificates with an expired date to go through. Note: you should not generally do this in production code. However, there are often times where you receive a support call at 2am because a mission-critical system is down, and you find out it is because of an expired certificate between the servers. Even if you control both servers involved, it is often necessary to bypass one (or both) temporarily to get a system limping back up. Yes, yes, yes I'm well aware its insecure to bypass one or more checks, but you have a choice to make. You keep a $1.5m account and run insecure for a few days by toggling a configuration setting to ignore a single wrong factor on the certificate, or you lose that $1.5m account. From a security standpoint, yes its risky. If the attacker has gotten hold of an old, expired certificate or a certificate in-transit that has not arrived yet, they can execute an attack. However, that person on the phone at 2AM under a support contract doesn't care that it is their fault the certificate expired, they just want the system back up and back up now. The big thing here is notification -- the user needs a notification of why you are denying their request. You can't just fail, you have to tell them why and, ultimately, should provide them with a decision point "continue or abort."

Friday, April 21, 2006

colgroup and ASP.NET

For Internet Explorer 3 or later, or HTML 4.01 (and XHTML), there is a colgroup tag. Here is a sample table using the colgroup tag:
Region / County / District Data
Ohio
Ohio Greene
Ohio Greene Xenia
Ohio Greene Fairborn
Ohio Montgomery
Ohio Montgomery Dayton
Ohio Montgomery Vandalia

The comment MSIE HTML Tag

In MSIE, there is a tag <comment> that indicates comments, in addition to the traditional HTML comment tag (<!-- -->). The issue with the traditional HTML comment tag is that you can't easily use it to comment out other HTML that could potentially contain comments. As such, its fairly useless for web applications (vs web documents) and AJAX applications. The comment tag, however, doesn't suffer this problem, since tags can be safely nested. This really ought to be put into the XHTML and XML standards. But it doesn't work in FireFox and standards-compliant browsers! To make it work in FireFox, add the following line in any style block in the document: comment, COMMENT { display: none; } This will work in all standards-compliant browsers. Some builds of Konquerer on Linux do not correctly add unrecognized nodes to the DOM, which prevents you from using techniques such as this to provide experimental or non-standard features via JavaScript. Note: for XHTML, the comment element should be isolated in its own namespace -- however many current generation browsers cannot apply styles to XML+NS. =/

Wednesday, April 19, 2006

The Float Model Problem

The Float Model Problem

I am no purist, and could happily live with a specification designed by Microsoft, but to have MS publicly support the specs while silently flouting them really burns my toast. Is this how the future is made?

It's past time that these issues were aired out. Gentle reader, if you know any way of 'getting to' the movers and shakers at Microsoft, won't you please try and shake loose some kind of information regarding future plans? I dread having to tell the next newbie that the simple, straightfoward CSS standards can't simply be used 'as is', because the majority browser maker refuses to conform as it supposedly has agreed to do. This situation has got to end sometime; why can't it be now?

Microsoft is flouting nothing. When Microsoft originally implemented the CSS1 (note: they only claim CSS1 compatibility) features, there was no working reference implementation, there was one other browser with any CSS1 support, and that support was legendarily bad. Internet Explorer is derived from Mosaic (the notification is still there in the about box, as required to use Mosaic code base). Netscape's Mozilla engine, as it stood through Netscape 5's end-of-development, was a reimplementation of Mosaic by the same folks who implemented it originally. If you remember Netscape 4.7 (think way back), it didn't handle much of anything right. Even early versions of the open source Mozilla (I'm talking very early versions) could not successfully render CSS. Here's a theory for you -- Mosaic was written before CSS existed, and so it did not take the needs of CSS into account when it was designed. As Mosaic derivitives, both Netscape Navigator and Internet Explorer inherited this limitation. This was resolved in the Mozilla code base when the browser's rendering engine was rewritten from scratch, resulting in Gecko. The new engine, which was written after the CSS3 specification was at a draft status, and after the mistakes of the first implementation was performed, is what allowed full conformance. When you look at IE 7, it still is using the mosaic engine at its heart. Microsoft has rewritten probably all of the code at this point, but it still, at its heart, is the roughly the same rendering system that Netscape and the Mozilla.org team never could get to work properly. I do want to point out that Gecko has plenty of CSS bugs, some of which have been open for 3+ years, have patches, and have had implementation in the actual codebase blocked by commercial companies such as IBM and Novell. And no, I'm not kidding. It disgusts me that it is "evil" when Microsoft implements a draft standard, but when FireFox implements portions of it with proprietary extensions, and uses properties incompatible with the draft standard, it's hailed as a standard's machine. What we really need to do is force CSS implementations over to the XML dialect, so that vendors such as Mozilla and Microsoft can use standard XML+NS for their extensions, and can use standard XML+NS to indicate the draft specification to which they are compliant, so that user agents, web design tools, etc. can deliver content based on that draft standard. Note the big thing here is this... It took Mozilla, without the potential of breaking huge corporate accounts and millions of end users, more than two years to get to its current level of CSS support. Microsoft cannot afford to break existing huge commercial accounts, nor millions of end users, and so this task is magnified probably an order of magnitude for them.