Miscellaneous Patches

From time to time I patch some bit of code or other.  In case I either haven't got round to submitting the patch back to the code maintainer, or the maintainer has chosen not to apply the patch, I'll post it here.

Cache::Memcached

Cache::Memcached, the Perl client bindings for memcached, don't work if Perl's "taint" mode is enabled.  At least, not for me they don't.  The error seems to be related to pos() somehow returning undef after a successful match (which, according to the Perl docs, it should not do).

The symptom of the bug is that you'll get warnings (assuming you have warnings enabled) from Memcached.pm:

Use of uninitialized value in subtraction (-) at Cache/Memcached.pm line 494.
Use of uninitialized value in substr at Cache/Memcached.pm line 495.
Use of uninitialized value in addition (+) at Cache/Memcached.pm line 498.

This patch works around the problem by not using pos() any more.

The latter patch was accepted into the Memcached codebase and is part of Cache::Memcached version 1.14.

Text::Unaccent

Text::Unaccent provides Perl bindings to "unac", a library for removing accents from strings.  Unfortunately if you accidentally pass in something other than a string (for example, undef, a number, or some sort of reference) then bad things can happen, including data corruption, process crashes and core dumps.

This patch makes it safe to pass non-string data to the module: doing so will simply cause an empty string to be returned.  This is not meant to be a complete fix - ideally the code should "stringify" its argument.  Rather, it's meant to save you from the embarrassment of a core dump just because you didn't spot a stray undef.

At the time of writing, I have not submitted this patch to the module's maintainer.

Update: fixed a glaringly obvious bug in the first patch, in the utf16 call.

HTML::Mason

Mason allows you to declare variables to receive parameters (query string, form) passed to your page:

	<%args>
	$key => undef
	</%args>

So $key will be whatever string was passed as the name 'key', or undef (if none).  The question is, what happens if more than one parameter called "key" is sent (e.g. yourpage.html?key=1&key=2)?  Mason's answer is to make $key a reference to an array containing those values ($key = [ "1", "2" ]).

The problem with this is that if you forget to check for and somehow handle these array refs, your code can end up looking pretty silly - for example, your site visitor might end up seeing an error like "User 'ARRAY(0x816e08c)' not found".  You could argue that Mason's behaviour is just fine and that the answer is simply to perform stronger validation of received values.  However it just seems wrong to me that I ask for a scalar and it might be a string or it might be an array ref - I prefer to know which type I'm going to be dealing with in advance.  And anyway, performing this sort of validation just seems like something which Mason should be able to do for me.

Hence, here is a patch to address this issue.  It creates a new Mason setting called "repeated_arg_into_scalar", which tells Mason what to do if a scalar argument was passed multiple values.  The choices are: "arrayref" (the default behaviour, see above); "firstvalue" (store the first value, throw away the others); "lastvalue" (likewise); and "error" (throw an error).

I did post this patch to the Mason users newsgroup, but no-one seemed interested.  Fair enough; I like it, and if you find it useful too, then that's fine by me.

djbdns

daemontools