I've sort of been toying around with AttackAPI over the weekend and interestingly, I figured out that I was vulnerable to a lot of the attack vectors that were present. But what javascript causes, javascript can fix too. So here's a quick fix to prevent an intruder from portscanning your local network for ftp or other ports.
FindProxyForURL: The proxy autoconfig file can be used to filter out requests to the naughty port scanners. The aim is to detect a bad URL, redirect it to a proxy which will log the referrer and raise the corresponding alarms. And to parse out the URL properly, I use the following regex.
var urlRegex = new RegExp( "^(([^:/?#]+):)?"+ // scheme "(" + "(//)?"+ // delim "(([^@]+)@)?" + // userinfo "([^/?#:]*)?" + // host "(:([^/?#]+))?"+ // port ")"+ "([^?#]*)"+ // path "(\\?([^#]*))?"+ // query "(#(.*))?$" // fragment );
After parsing out the URL, my very simple filter checks for a port value which is suspicious (i.e below 1024 and not 80) and redirects it to my local logging proxy which eats the request. I still haven't figured out a way of leaving a honeypot for attackers to ensure there's a human at the other end.
function FindProxyForURL(url, host) { var m = url.match(urlRegex); if(m) { var port = m[7]; if(port != "" && port != "80" && port.length < 4) return "PROXY 127.0.0.1:4242"; } else { return "PROXY 127.0.0.1:4242"; } return "DIRECT"; }
It should be perfectly possible for this technique to be extended to prevent XSS exploits with javascript land checking for common XSS attack vectors. But the essential problem is that this particular function cannot maintain context easily. The previous request cannot affect the current one, nor the current one affect the next request. Having minimal ability to learn does cause a large number of problems for a really practical solution - but if there is already such a hook, it might be possible to hook an extension into it.
--Too many people are thinking of security instead of opportunity.
-- James F. Byrnes
posted at: 01:23 | path: /insecurity | permalink |
For any php performance freak, include_once has been a pain in the neck for a long time. In a previous post I had talked about how the common workarounds affect something like APC. With the release of APC 3.0.14, there is a decent workaround which doesn't require any changes to the php code. But first, let me drag out another almost-workaround to the whole include_once problem.
rinclude_once: So we create a new function for the purpose. Let me just call it rinclude_once and use that everywhere. The function takes in the filenames, pushes it into a hash before including it.
function rinclude_once($file) { global $rinclude_files; if($file{0} != '/') return include_once($file); if(isset($rinclude_files[$file])) return; $rinclude_files[$file] = true; include($file); }
This bit of code works - but only for absolute filenames. I put it through its paces without apc against include_once. Surprisingly, without APC, this code is slower than the php engine's include_once checks. That somewhat makes sense because the extra include for the rinc.php makes a slight dent into the compile and execution time, overshadowing the cycles wasted in the include_once syscall land.
Excluding the slight blip in performance, both the bits of code are nearly neck-to-neck. The real cost of include_once is only evident when you throw in APC. For every file which was included, include_once opens the file before checking for multiple inclusions. The extra system call shows up in the graph below. But the rinclude_once does not work at all for relative path includes (the second pair of bars) and therefore trails badly in this race for performance.
include_once_override: The solution to this problem is freakish. APC meddles with the brains of the Zend interpreter and inserts its own version of ZEND_INCLUDE_OR_EVAL opcode handler. The new handler does not indulge in the gratuitous fopen idiocy present in the default handler (but it does fopen once) and checks for the filename in EG(included_files) hash before doing a normal include() (thank pollita for that). And it should come as no surprise that the C module outperforms the php land equivalent.
But all of these only work for absolute paths as the pathetic numbers on the relative path includes shows. That is where the path canonicalization kicks in. In APC's nostat mode, the filenames have to be absolute paths for the mode to be useful. But rather than force everyone to modify their include lines, APC rewrites the constant strings into the corresponding path names, after lookup. Essentially it converts all relative path includes, such as those from the pear paths, into absolute path includes. This works well with the stat=0 mode because file modifications are ignored after caching.
At last, we see both the relative and absolute includes touching the same level of performance - because they are no different from each other in opcode land. But as you can clearly see, that does not improve the performance of the relative include for the rinclude_once because it does dynamic includes. The opcode cache cannot determine what the value of $file will be for the include_once($file); line and cannot optimise that. The performance actually takes a dive because the relative path name passed in has to be full resolved for every request.
But having said all this, the same benchmark with plain includes is faster than any of these. I think there is a fair bit of optimisation left in this beast, but what is needed for that is the rest of the world to disappear while I code. Deep hack is hard to achieve when you're a ....
--You can't second-guess ineffability, I always say.
-- Good Omens
Goodbyes are hard to say. The heart still hopes that in this small world, our paths shall again cross.
My voyage ran aground into one of those moments today - sabiokap's last day in Yahoo! Bangalore. He's been the joker in our pack, inventor of crazy games and a very good friend. We all were nightbirds who used to hangout together and in general formed the resident population of the office nearly 24x7. Sitting up in the balcony at 2 AM in the morning was actually fun when everybody thought there was a point to working hard & long - and we liked it.
But more than just at work, he's been someone for me to lean on when my life was shaky. When I was penniless and homeless after booking my LCA 07 tickets, I crashed out in his guest room for four months. I managed to get out of that financial hole thanks to premshree spotting me some dough and accomodation at Hell's Kitchen (that's what we call sabiokap's place, for good reason).
There was a certain bit of company ethos that is oozing out slowly to various other places these days. The day (or well night) of the workaholic hacker is gone, obsoleted by the eary morning meetings. The concept of working with each other replaced by working as team, under the bidding of a manager. The days don't pass so easily and to pour the company into a new mould needs a cultural genoicide of sorts. But well, the good thing is that I was here for those good old days - work hard, play harder and don't care what else happens.
I don't hold any grudges against anyone, but all this takes away the thing I loved about this company - interesting people and good friends. For whatever reasons, good or bad, people I like working with are leaving, those with attitude, talent and a sense of humour. All I can do is wish them Godspeed.
That's how it ends, not with a bang but a whimper.
--philosophy:
The ability to bear with calmness the misfortunes of our friends.
Poetry is not my forte. But even my prosaic soul was stirred up the caustic wit and wordplay of Dorothy Parker's poetry. My first run-in with her poetry is thanks to spo0nman, who showed a single verse about three months back - that one verse remains scrawled on the corner of my whiteboard to this day.
Drink and dance and laugh and lie, Love, the reeling midnight through, For tomorrow we shall die! (But, alas, we never do.)
Ah, poetry like such has to be read again. The flash of brilliance on the last line, twisting everything said before into its opposite. To lead you down one path of thought, only to yell - Ha, you didn't see that coming is hard to do with poetry. Yet she does, but not without sacrificing brevity or any of the other flourishes that poets are wont to do.
There is a certain cynical poke at the foibles of mankind, of the ephemeral pains of the heart, of the dissolution of the soul, which says more between lines than the average page of a novel, yet compressed into verse. There is a certain bitterness in her work, but one not borne out of sadness, but of defiance at a world which disappoints. Yet somewhere, we see a hopeless paradise carved out of this world with knifes and daggers of cynicsim. And still, to give up sadness is not an easy sacrifice to make.
When I am old, and comforted, And done with this desire, With Memory to share my bed And Peace to share my fire, ... I'll forget the way of tears, And rock, and stir my tea. But oh, I wish those blessed years Were further than they be.
But there is humour and fun in this hidden - but only for those whom it comes unbidden. It is not quite verse that I penned, but in my life worse I have sinned. Inspired me she did with her sorrow, but with an ounce of talent of hers to borrow (for it is a poor poet who does not inspire).
The themes are slightly odd for a contemporary of Wodehouse, verging on the suicidal, bittersweet and mordant. But the soul searching gives way to girlish glee in such twists that this reader is left speechless. The gift of repartee is unmatched except perhaps by Nancy Astor on the other side of the Atlantic pond.
Thankfully, a fair bit of her work was done before 1923 which means that the copyright restrictions no longer apply to the work. You can get a fairly large collection of her poems from Poem Hunter as a very convenient pdf file [650k]. Take a good close look at some poems in there like the Burned Child, Recurrence, The Evening Primrose or Surprise.
And it still echoes back But alas, we never do ...
--Four be the things I am wiser to know:
Idleness, sorrow, a friend, and a foe.
-- Dorothy Parker
Over the last month, I've been poking around OpenMoko. The real reason was because toolz had a prototype phone with him. But the real reason I got anything done on the platform is because of the software emulation mode, with qemu-arm. The openmoko wiki has a fair bit of detail on running under QEMU - but if you just want pre-packaged ready to run QEMU images, take a look at jebba's pre-built images. All I've added to that is the qemu tun-tap network adapter ( -net nic -net tap ) so that I can scp stuff in & out of the phone image. Here's how the applications actually look on the emulator phone (it is *very* CPU heavy - if you have a Core2Duo or something, this would be a nice time to take a look at man taskset(1))
pnet on moko: Back in 2005, krokas had built the OE based packages for pnet. So essentially, building pnet ipks for OpenMoko is no different from building it for any other OE platform, especially because pnet hsa nearly no dependencies on anything beyong libc and libX11.
But the register asm() trick pnet uses to ensure that values like program counter and frame pointer are stored in the correct registers does not work on arm gcc-4.1.1. Aleksey has implemented a couple of solutions like the __asm__ barriers. But as of now, the engine is running in pure interpreter mode, which is not fast enough.
The emulator mode is pretty decent - even with the stock qemu-arm. If my interest keeps up, I'll probably try the OpenMoko patched qemu. I did build the whole toolchain and rootfs from scratch with MokoMakefile - but monotone is really painful to set up and the entire build takes a whopping 14 gigs of space on my disk. So if you're thinking of playing around with moko, don't try that first up :)
--Telephone, n.:
An invention of the devil which abrogates some of the advantages of making a disagreeable person keep his distance.
-- Ambrose Bierce
Recently AfC wrote a HOW post on linux & open source, but the question I'm more often asked is WHY.
Most of the content in this entry comes from the similarly titled GNUnify 2006 BoF session with inputs from spo0nman, premshree, lunatech, pradeepto, G0SUB and the students at the conf. And it attacks the topic from the other side of the problem - what more does a F/OSS programmer bring to the table at a job than the other guy.
Not Technical Talent: For a long time, I had assumed that it was the proven technical competency which has been tested in the real world. But in the recent past, I've met enough technically adept folks from both sides of the divide to take that assumption to peices. People from the proprietary code land are equally capable and just because your code is open does not make it any better by default. Having your code out in the open does make it easier to judge your ability for a third party - but that'd be end of this blog entry if a programmer was merely a code producing machine.Co-operation: The transition from college to the workplace is rather jarring. Having spent the last fifteen-odd years in constant competition with your peers, suddenly you are thrown into a world where you need to co-operate with, rather than screw over, the next guy. Most people who work in a successful open source project with multiple contributors have gotten past that particular hurdle much more earlier and the transition into a workplace where the focus is on getting things done rather than merely doing your own part is much more easier.
You got Bugs ! (and users): I've often been shocked by the way people deal with bugs and criticism. The immediate 'full power to shields' reaction is probably understandable, but rather unpleasant. But for someone who has worked with other people in a serious project, criticism from your peers is easier to handle or at least something they have handled in the past (or you'd think so). Also bugs from end users gives a developer some level of user focus which is totally absent in the college graduate. Seeing the user and his problems as one of the factors while coding is hard to acquire if you've written code for a college professor to run once.
Communication Skills: Most f/oss teams are spread across the world. Their communication happens mostly through filtered channels such as mailing lists, irc or bugzilla. It does take some effort to involve yourself in such a global environment when communication can be easily misinterpreted for tone and context. Working in such an environment easily carries across into the modern world of distributed development required for global product development.
Consensus: Have you ever been in a technical argument at work ? There are always people who have a hard time accepting someone else's point. If you've worked on a real peice of code long enough with a group, you've had one of these hard-to-swallow decisions to deal with. It does come as a nasty surprise to most graduates out of college when they run into one of those. Having gone through the standard sulk phase for the first few such run-ins, most f/oss developers are more understanding and less obnoxious about accepting someone else's idea.
Oh the humanity !: Somehow, getting involved with a project, working with different people and enjoying the experience does result in a more rounded work persona. The whole community effect can easily seperate the assholes from the good guys as easily as it seperates the men from the boys (uh... women from the girls too). In general, it also selects for a person of the community rather than the brilliant loner and most employers prefer the former.
There are many more qualities which are quintessential to the f/oss hacker ethos - passion, commitment and plain old curiosity. But they are not unique to the group - anybody who has run into a mac fanboi would agree on the passion part at least :)
I'm by no means the first guy to say that F/OSS hackers are better hires - virtual referral and loudthinking do reinforce my conclusion - but someone needs to tell the students.
--Yacc owes much to a most stimulating collection of users. Their irritating unwillingness to learn how to
do things my way has usually led to my doing things their way; most of the time, they have been right.
-- S.C Johnson.
Happy Vishu to everyone ! For those of us that follow the Malayalam calendar, this marks the birth of the new year. Vishu has like, totally been my favourite festival for so many reasons - it is bang in the middle of the summer vacation, being a kid means you cash in with Vishukkaineetam from all your elders and lastly *FIRECRACKERS* !!.
Because I'm in mourning, I'm not actually celebrating Vishu this year, but that doesn't really stop me from being carried away by the old sounds and smells remembered from the days of my childhood. Ah, nostalgia ... the consolation prize of a loss. For the last 15 years, I've never missed a year in spending this particular day with most of my extended family.
Well, I guess this makes it sixteen in a row ... :)
--We used to call him April Showers, because he brought May flowers.
-- P.G Wodehouse, The Small Bachelor
After much thought and inaction, I've compiled a quick list of basic things you can do at work to reduce your tangible value to the company (coming to a bank account near you, soon !).
- Answer questions on devel forums
- Write a technical blog
- Live the company values
- Write cool hacks
- Have a serious hobby
- Contribute to an open source project
All of these things shout out that you have too much free time. If you send detailed, well thought out answers to a question on a devel forum - you aren't working hard enough. If you've got time to write a decent blog about technology - you aren't working hard enough. If you actually live the company values (for instance, like I do) - your irreverance and sense of humour do not suit a professional in this business. So is going around your product managers to actually build something that you personally like, without any input from the product strategy team - that's not what you get paid for. And hobbies - they waste your time and cost you money. Without a hobby to spend your disposable income on, you won't need as much money as you're asking for now.
But the last one takes the cake. Assume your full time job involves working on an open source project. Now answer me this, "what *competitive* advantage does your work bring to this company ?". After all the code that you write automatically becomes available to everybody - irrespective of who paid for the development costs. Code thus released drops to near zero value and ergo, the process of creating it ...
These should just about work, but YMMV.
PS: I'm being seriously *sarcastic* (or tersely ironic) here - these things are a potential investment in your betterment, do them, be a better person and as the Bhagavat Gita said - Karmanye vadhikarasthe, ma phaleshu kadachara (do your duty and expect no reward).
--The term investment (the basis of all capital) is pretty much forgotten.
Instead, investing money is considered spending it.
-- slashdot #18632805
While on my way back from Sydney on Singapore airlines, I ran out of things to do. Now, rather than play Mario on their onboard entertainment, I took a look at their comedy section. That's how I saw my first episode of Futurama - Roswell that ends well. And I was a fan in a few minutes. Thanks to set of borrowed DVDs, I've finished watching every single episode - yup, all 72 of them. I love the series for the the very same reasons I love the other Matt Groening creation - the Simpsons. The referential coherence of both series shows a nearly impossible amount of research put into the script and story line.
Good News, Everyone: Just like every other good cartoon, the jokes are at every level of the series - the characters, situations and even tag lines. In fact, the whole plotline is one giant inside joke about how things change, yet stay the same. For instance, Fry who was a delivery boy in the year 1999, ends up as a delivery boy in the year 3000 - except the deliveries are now to far-off planets, rather than to city blocks.
The Characters: The character set for the show is literally identical to my standard comedy situation. A befuddled hero, a self-confident heroine, one weirdo side-kick and then a couple of total reverse stereotypes. This is literally identical to say, h2g2 (Arthur, Trillian, Zaphod) or Coupling (Steve, Susan, Jeff) - we find Fry, Leela and Bender in each of those slots. Of course, Futurama would be a non-starter without Bender (aka Bender Bending RodrÃguez). Rather than being a logical minded machine, he's the ultimate personification of the human vices - drinking, smoking, swearing, gambling, stealing ... in short, the whole deal. Or take the professor for instance, who is actually Fry's nephew by a long way, but is older than Fry. Even Dr Zoidberg, who sounds like a Jewish doctor but is not a doctor (heh, the intro sequence is amazing) and of course, a shellfish (i.e not Kosher). Even Leela, whose one eye gives her no depth perception which is actually essential to flying an aircraft. Add a rich intern, a rastafarian accountant, a shatner clone in short underpants, a robot devil (Beezelbot), a killer Santa - stop laughing !
Cultural Leakages: Bender's "bite my shiny metal ass" has moved out the world of cartoons into being a real cult phrase. For instance, if you do a reverse dns lookup of the pirate bay servers you'll get bite.my.shiny.metal.ass in the domain name. I occasionally run into even more obscure Futurama references such as "What ? My mother was a saint !" in response to utter gibberish. Even the "Why worry about this planet ? It's not like this is the only one we got" makes me smile, although wryly.
Episodes: If I had to pick a couple of favourite episodes. I'd definitely pick Spanish Fry as the one I liked best. The concept of poaching humans for their human horn truly draws parallels to the african rhino situation. The Godfellas episode is also thought provoking - especially the last few minutes. And the section about greenhouse effect in the Crimes of the Hot truly belongs in an educational film - especially the silencing of the questioning child. There are touching episodes as well, like The Sting or The Luck of the Fryrish - both of which have heart-tugging endings.
Language: Every good Sci-Fi sequence requires its own language. Futurama doesn't just stop at using new words like Blernsball or Slurm, but also goes onto redefine some old words like XMas which is pronounced as it is written and nobody remembers the Christ part of it. They even went further to invent a whole new alphabet to put alien messages in. Here's how it actually looks - I wonder if I can get a t-shirt printed (but nobody except Futurama fans will get it).
All in all, a thoroughly enjoyable but pleasantly thought-provoking animated series for educated adults.
--You can't go faster than the speed of light.
That's why scientists increased the speed of light in 2208.
-- Futurama, A Clone of My Own
X11 programming is a b*tch. The little code I've written for dotgnu using libX11 must've damaged my brain more than second-hand smoke and caffeine overdoses put together. So, when someone asked for a quick program to look at the X11 window and report pixel modifications my immediate response was "Don't do X11". But saying that without offering a solution didn't sound too appealing, so I digged around a bit with other ways to hook into display code.
RFB: Remote Frame Buffer is the client-server protocol for VNC. So, to steal some code, I pulled down pyvnc2swf. But while reading that I had a slight revelation - inserting my own listeners into its event-loop looked nearly trivial. The library is very well written and has very little code in the protocol layer which assumes the original intention (i.e making screencasts). Here's how my code looks.
class VideoStream: def paint_frame(self, (images, othertags, cursor_info)): ... def next_frame(self): ... class VideoInfo: def set_defaults(self, w, h): ... converter = RFBStreamConverter(VideoInfo(), VideoStream(), debug=1) client = RFBNetworkClient("127.0.0.1", 5900, converter) client.init().auth().start() client.loop()
Listening to X11 updates from a real display is that simple. The updates are periodic and the fps can be set to something sane like 2 or 3. The image data is raw ARGB with region info, which makes it really simple to watch a particular window. The VNC server (like x11vnc) takes care of all the XDamage detection and polling the screen for incremental updates with that - none of that cruft needs to live in your code.
Take a look at rfbdump.py for the complete implementation - it is hardcoded to work with a localhost vnc server, but it should work across the network just fine.
--You can observe a lot just by watching.
-- Yogi Berra
In one of my previous posts, I'd commented off-hand that the Indian F/OSS community doesn't have enough rockstars. But that by itself blossomed out into a rather heated debate on #linux-india, mainly because we never got to hear lawgon's wisdom on what actually is lacking in India. The debate was more tilted towards the effects of the so called "rockstars" than their origins, causes and well ... mating habits (Freud made me do it !).
But before you actually read this blog entry, I'd advise you to watch Kathy Sierra's talk from LCA '07. You can download it from here [101 Mb]. I'll be borrowing some of her terms and ideas because they talk about how people get involved and become passionate users.
Burn Through the Zone: Success is often a matter of persistance. Most people hit the "Why Bother" phase in the first few weeks of trying something new. But what keeps the persistant folks going is the knowledge of an attainable goal, a sort of beautiful picture of "what could be". The so-called "rockstar" of the community is on such a pedestal of achievement. Bereft of such an example, there will be hundreds who hit their first snag and quit - people who are capable, but don't see it worth their effort. Or maybe they just ran into the "I suck" zone, in Kathy Sierra's words (or well, pictures).
The rewards for being good at something have to be obvious and evident for people to try their best - therefore they work hard and succeed - which is a circular argument from the outside. After all only an idiot would set himself on a mission with no goal and idiots aren't our target audience here.
Emulation Mode: The biggest problem people have with this concept is that a rockstar lends hiself to emulation, producing fad-followers rather than future leaders. But the whole basis of human culture and learning has been mankind's ability to recognize a good thing when it sees it and of course, to imitate by whatever means available. You learn more by doing than seeing and the obvious way to gap that bridge is to attempt what the other idiot/genius is doing.
The right people will split out of pure emulation mode very quickly, as they realize their innate urge to do their own thing. And in any case, people who can follow in a clear (albeit beaten) path are still valuable to any community. I personally prefer them over the self-propelled idiots :)
"Coolness" factor: During the formative years of your life, for a large number of reasons, you do what's cool. The urge to stand out or blend in, as the need be, is something which primeval and probably the conflict of which is the essential misery of man. The effect of the rockstar (who by definiton is cool), is to add an aura of coolness to the act of contributing to something. But for some strange reason, coolness is unacheivable in a group of peers.
The rockstar himself is part of the coolness ying-yang as well. In the real world, without a suitable audience to shower admiration, the hacker has nothing to aspire to but some obscure achievement in a world of peers who would rather play down your work compared to theirs. I think jace had called it the Great Wall of 'So What ?' - where anything you did can be dismissed by these two magic words.
The hard part of being a rockstar is not to put up such walls when someone new comes into the community. Trivializing someone's work is hardly a great way to welcome someone into a group and can be perceived as an outright dismissal of someone's hard work. And indeed it does happen to every other developer, at some point or the other.
Honestly, half the "Because I can" people are into it because it's cool ;)
Beacons: In a community with an insanely large number of potential contributors, it is nearly idiotic to try to seperate the chaff from the grain by brute-force. A rockstar by this definition is an evangelist by action and a touch-point by reaction. A prominent figure outside his or her area of action attracts a lot of potential talent who can then be nudged towards potential mentors who have the time & talent, but not the visibility.
Such rockstars, who inspire/guide/find contributors are required for any community. They are the glue that holds together the gears that drive the community (oh, I kid ... I kid). They are like tiger in the jungle, their visibility & influence indirectly showcases the community - to those outside the community.
Communities grow anchored to such people - their visibility and the ease with which they can handle that is a valuable asset to the community. But it is possible to overdo it as well - you know the examples ...
--The key to building a superstar is to keep their mouth shut.
-- - Bob Ezrin, rock music producer
posted at: 06:40 | path: /observations | permalink |
APC 3.0.14 (code named "A bigger boy made me do it, sir") went out a couple of days ago - read the release announcements. The major things in the release is a fair bit of performance improvements for those don't use threads. Also I've figured out a quick way to limit memory fragmentation when APC user cache (apc_fetch/_store) is heavily used - the new fraglimit fixes should solve all the small fragment issues with 3.0.13. And following my recent obsession with drawing pretty graphs for everything, here's how the old version looks compared to the latest code (requests per second for an include_once benchmark).
To get to such levels of performance, the code has some configuration parameters that can be set. The apc.localcache creates a process (yes, not thread) specific lockless cache which is basically a layered shadow cache ontop of the same shm data. The apc.include_override_once is also now usable because of the appropriate checks put in to reduce the overhead of include_once. And now, when you enable apc.stat there's a bit of code which pre-computes the path of the included file so that it can be effective for includes with relative paths or from include_path dirs.
The release is hopefully stable enough to provide someone with enough ramp-up time to get started, if I stop working full-time on APC. I've spent a fair bit of time stabilizing basic functionality and have kept most of these optimisations optional, to be able to look at other work for a while.
--Periods of productive stability, interrupted by bursts of test-bed change is much less disruptive than constant ripples of change.
-- Fred Brooks Jr, "The Mythical Man Month"
I don't have flash on my machines. More than a mere security and convenience measure, it is one of those things enforced by Adobe themselves - by refusing to ship an EM64T/AMD64 build of its mozilla plugins. So when the flickr organizr went Javascript I was happy. But they took away a bit of code which made it really easy to rotate images - because you couldn't do it in Javascript.
But you can. I don't mean with some memory hogging clientside bit twiddling but with the now popular HTML 5 Canvas. So, with a few lines of Greasemonkey code, which you can pull from here, I can now push in image rotate previews back into flickr's organizr. The code has to be run outside greasemonkey land to get full access to the dom data, which I accomplish with the following script insertion.
var _s = document.createElement("script"); _s.appendChild(document.createTextNode(window.myFun.toSource() + "();")); document.body.appendChild(_s);
And just in case you happen to be an IE user, you might want to see if EXCanvas can make my canvas code work decently there.
--enhance, v.:
To tamper with an image, usually to its detriment