Ссылки о веб-разработке за декабрь 2008

MD5 под SSL успешно атакован

Shared by iz
Вот уж действительно отстой. Practically undetectable man-in-the-middle attacks. Хотел за инет заплатить, а теперь боюсь в интернет-банк заходить.

С новым Годом, господа и дамы системные администраторы. В Берлине сегодня была представлена рабочая схема фальсификации SSL-сертификата, основанная на коллизиях алгоритма MD5. Атака распространяется на сертификаты, выданные CA, использующими MD5 для цифровой подписи: RapidSSl, FreeSSL, TrustCenter AG, RSA Data Security, Thawte, Verisign Japan:

As a result of this successfull attack, we are currently in possession of a rogue Certification Authority certificate. This certificate will be accepted as valid and trusted by all common browsers, because it appears to be signed by one of the root CAs that browsers trust by default. In turn, any website certificate signed by our rogue CA will be trusted as well.

оригинал: http://moskalyuk.name/1816

Researchers Show How to Forge Site Certificates

Today at the Chaos Computing Congress, a group of researchers (Alex Sotirov, Marc Stevens, Jake Appelbaum, Arjen Lenstra, Benne de Weger, and David Molnar) announced that they have found a way to forge website certificates that will be accepted as valid by most browsers. This means that they can successfully impersonate any website, even for secure connections.

Let me unpack that for non-experts.

One of the cornerstones of web security is the use of secure connections. When your browser makes a secure connection to (say) Amazon and gets a page to display, the browser displays in its address bar a URL like "https://www.amazon.com". The "https" indicates that the secure (https) protocol was used, and the browser also displays a happy blue lock or key icon to tell you the connection was secured.

The browser cooperates with Amazon's web server to secure the connection via a two-step process. First, the two computers negotiate a shared secret key that they can use to communicate privately, using crypto tricks that I won't describe here. Second, your browser authenticates Amazon's web server, that is, it assures itself that the party on the other end of the connection is the genuine Amazon.com server.

Amazon has a digital certificate that it sends to your browser, as part of proving its identity. The certificate is issued by a party called a certification authority or CA. Your browser comes pre-programmed with a list of CAs its trusts; you can change the list but hardly anyone does. If your browser makes an encrypted connection to "amazon.com", and the party on the other end of the connection owns a certificate for the name "amazon.com", and that certificate was issued by a CA that your browser trusts, then your browser will conclude that it has a secure connection to amazon.com.

Now we can understand what the researchers accomplished: they showed how to forge a certificate corresponding to any address on the Web. For example, they can forge a certificate that allows themselves, or you, or me, or anybody, to impersonate amazon.com, or freedom-to-tinker.com, or maybe even fbi.gov. That is supposed to be impossible, for obvious reasons.

The forged certificates will say they were issued by a CA called "Equifax Secure Global eBusiness", which is trusted by the major browsers. The forged certificates will be perfectly valid; but they will have been made by forgers, not by the Equifax CA.

To do this, the researchers exploited a cryptographic weakness in one of the digital signature methods, "MD5 with RSA", supported by the Equifax CA. The first step in this digital signature method is to compute the hash (strictly speaking, the cryptographic hash) of the certificate contents.

The hash is a short (128-bit) code that is supposed to be a kind of unique digest of the certificate contents. To be secure, the hash method has to have several properties, one of which is that it should be infeasible to find a collision, that is, to find two values A and B which have the same hash.

It was already known how to find collisions in MD5, but the researchers improved the existing collision-finding methods, so that they can now find two values R and F that have the same hash, where R is a "real" certificate that the CA will be willing to sign, and F is a forged certificate. This is deadly, because it means that a digital signature on R will also be a valid signature on F -- so the attacker can ask the CA to sign the real certificate R, then copy the resulting signature onto F -- putting a valid CA signature onto a certificate that the CA would never voluntarily sign.

To demonstrate this, the researchers created a forged certificate signed by the Equifax CA. For safety, they made the forged certificate expire in the past and point to a harmless site. But it's clear from their description that they can forge a certificate for any site they want.

Whose fault is this? Partly it's a consequence of problems with the MD5 hash method. It's been known for a few years that MD5 is in the process of melting down, so prudent designers have been moving away from MD5, replacing it with newer, better hash methods. Similarly, prudent CAs should not be signing certificates that use MD5-based signature methods; instead they should insist on signature methods involving stronger hashes. The Equifax CA did not follow this precaution.

The problem can be fixed, for now, by having CAs refuse to create new MD5-based signatures. But this is a sobering reminder that the certification process that underlies web site authentication --- a mechanism we all rely upon daily --- is far from bulletproof.

Рунет-2008: тренды года

Двуглавый медвед и газомасоны, сосальные сети и блохосфера, руботы и огребаторы, хламур и святназ - и все прочие радости русского Интернета, о которых вы боялись спросить.


A Web Developer's Responsibility

It's safe to say that the biggest tax on a web developer is spending so much time dealing with browser bugs and incompatibilities. Thus it has become the favorite past-time of all web developers to complain about having to deal with them. Browser bugs are annoying, frustrating, and make your job incredibly difficult.

Because browser bugs are so frustrating and such a burden on top of normal development it should be the responsibility of every web developer to make sure that the browsers they develop for are able to find and fix their bugs. By taking responsibility for the bugs that you find - and to not assume that "someone else will find it" - will accelerate the rate at which browsers can improve.

The solution to helping browsers is two-fold: 1) Every time you find a browser bug, file a bug report to the respective browser. 2) Actively test your sites in the latest builds of the major browsers.

The vast majority of web developers have never filed a bug report with a browser vendor - or even used a nightly version of a browser - which is a shame. If you think about it there are few who are more qualified to assess what is going wrong in a browser than those who spend every day developing for them.

I'm especially surprised when I see professional developers not filing bugs with browsers, or testing on nightlies. Since one of the primary tasks of most developers is to paper over cross-browser issues it becomes in their best interest to see the number of bugs reduced (and making their job dramatically simpler).

I've personally filed bug reports with every major browser vendor and I've noted a couple characteristics that make for a good report.

How to File a Good Bug Report

The three points that make for a good bug report are: categorization, test case, and reduction. Any bug that is categorized correctly and provides a reduced test case is guaranteed to be reviewed by a browser developer.

Let's start with where to file the bug itself.

Filing a Bug Report

Frequently when you go to file a bug report you have to wade a couple layers deep before you can get to the actual submission form. I've provided direct URLs to the best forms to use, below.

When you're filing your bug be sure to also test it in the latest nightly of the browser you're filing against (which I'll describe later on). This will be one of the first things that a browser developer asks. If you can show that the bug still exists in the current development version of the browser, that it has not been fixed, then it'll be that much easier for them to get started.

Note: Many of the bug report pages require that you create an account before submitting a report. This is an annoying one-time cost.

Categorizing the Bug

Categorizing a bug properly is an important first step. Frequently the owners of particular modules (such as layout or DOM) watch all new submissions that come in. Assigning a bug to the correct category will instantly put it before the eyes of the very person most capable of fixing the bug.

The categorization of a bug depends on the browser (some browsers, like Opera and Internet Explorer), provide simplified categories for filing a bug while others (WebKit/Safari and Mozilla/Firefox) use complex categories to denote the specific module where a piece of functionality might exist.

Mozilla/Firefox: Choose a Component. Some of the most common ones: DOM, Layout, JavaScript Engine.

WebKit/Safari: Choose a Component. Some of the most common ones: HTML DOM, Layout and Rendering, JavaScriptCore.

Google Chrome: Figuring out if you should file for Chrome is tricky. First test your bug in both the latest release of Safari and in the latest WebKit nightly. If the bug exists only in Chrome then file there, otherwise file the bug with WebKit/Safari. One problem, though: Bugs that only exist with the Chrome JavaScript engine (V8) should be filed in the V8 bug tracker instead of the Chrome one (lest it get lost in the shuffle).

Also, Chrome does not provide an explicit means of categorization. All bugs are reviewed by a developer and then categorized (you have no control over this process).

You should also take the quick step of testing on more than one platform (OS X and Windows, Windows and Linux, etc.). Simply determining that the bug exists on more than one platform can dramatically help to reduce the time needed to locate the cause of the bug by the browser developer.

Providing a Test Case

Any type of reproducible test case is better than nothing. A web page that's able to encapsulate the problem is generally a good start. If the web page is able to be attached to the bug report directly, that's even better (it may take a while for the browser developer to get around to your ticket and if your test case no longer exists at the URL that you specified then they'll likely just close your ticket and move on).

That being said there is such a thing as a bad test case. The worst kind is something like: "I have a web site at http://example.com and it doesn't work in browser X, please fix." That will take someone a considerable amount of time to locate the exact reasons for failure and will likely push your bug much farther back on the queue.

The best kind of test case is one that provides a reduction.

Providing a Reduction

Providing a simple test case is absolutely the hardest and most frustrating part of creating a bug report - but it's also the point that'll make your report most likely to be noticed and fixed. Even for the most qualified developers it should take no more than 30 minutes to create a good-enough test case.

The process for creating one is simple: Take a page that has the bug in it and rip out anything that doesn't affect the reproduction of the bug. This includes stylesheets, images, JavaScript files, JavaScript libraries, and HTML.

For example, a while back when I was running the Dromaeo test suite and I noticed that WebKit kept crashing when it hit a certain point. I began by ripping out tests, unnecessary HTML, CSS, and images. I eventually worked my way down to a single test: Splitting a string. I then worked to strip out as much of the test suite as possible so that there were no external dependencies required.

Note the final result:

var str = "", ret, fn = [];

for ( var i = 0; i < 16384; i++ )
  str += "a";

for ( var i = 16384; i <= 131072; i *= 2 ) (function(i){
    ret = str.split("");

  str += str;

window.onload = function(){
    if ( fn.length )
  }, 13);

What was left was about as simple as you could get while still having the crash occur. This is a good reduction. Based upon this reduction the reason for the problem was quickly identified and resolved just a couple weeks later.

Is my bug being worked on?

This is a challenging point - but one that's easier to determine with Mozilla/Firefox, WebKit/Safari, and Chrome (since they're all relatively open projects). Here's the best way to determine the status of the bug with each of those browsers.

Mozilla/Firefox: Your bug will start out being assigned to the default contact for the component category that you originally selected. This doesn't mean anything, yet, it's simply attracting people in to look at your ticket. People will start to CC themselves in to the ticket (which means that they're interested in its progress). The defining moment, though, is when someone assigns the bug to themselves, effectively stating that they are taking responsibility for the status of this bug. Most contributors have it set up so that any future comments on the bug are automatically emailed to them so if you have any questions about the status of the bug you can feel free to post a comment - but please do so at a reasonable pace (asking for daily, or even weekly, updates would be frustrating).

WebKit/Safari: WebKit uses a very similar setup to Mozilla/Firefox - just look for someone to take control of the bug and drive it to completion. The golden ticket, though, is when your bug "goes to rdar". Radar is Apple's internal (private) bug tracker. Having your bug move to there means that your bug is, effectively, guaranteed to be completed at some point (if not by the person who 'owns' it then by another Apple employee). Since Apple is still the major driving force behind WebKit updates having your bug move to rdar is what you should be hoping for. That being said, since rdar is private to Apple employees you no longer get the benefit of knowing if or when your bug will be completely fixed - it's just a waiting game.

Chrome: Chrome uses a system very similar to Mozilla/Firefox. Be sure to keep up communication with whom the bug is currently assigned to and to answer any questions that they might have.

If your bug eventually gets resolved then congratulations! You just helped to make the web a better place for everyone.

But that's not always the case.

What happens if my bug gets rejected?

Rejected bugs fall into two categories:

  1. It was rejected because it was not a bug.
  2. It was rejected because they browser vendor does not feel like working on it.

The first point is broken down into two further sub-categories:

It's legitimately not a bug. Congratulations! You've learned something about a standard, or some other browser obscurity, that you weren't familiar with: you're now a better web developer! You should fire up your blog and write about the obscure new bug or API that you discovered and explain it to the world.

Or it is a bug and the owner unnecessarily closed it. At this point you need to argue your case to re-open it.

The second point (the vendor does not feel like working on it) is also handled in two ways:

First, argue your case for the bug. This should help inform the browser developer that they should dedicate valuable resources to fixing this issue.

Or second, if they are truly unwilling to fix the bug: Raise holy hell on your blog, Twitter account, and any other place where other web developers will listen to you. If you can't find anyone else who agrees with your plight then you are probably crazy - but if it's a legitimate problem that the browser vendor is refusing to fix then you should easily find others with whom you can band together and complain openly to. But that's OK: You've earned this right. By doing all the due diligence necessary to bring this bug to light you earn full privileges of bitching about it in every other sentence.

Arguing a Bug

So you're at the point where your bug has been closed and you need to convince the closer that this was a mistake - that what you have is an actual, legitimate, bug.

Here are some of the best arguments that you can use, in order of which they should be used:

  1. Show that the bug was a regression. Prove that it was something that worked in a previous release that stopped working because of a change. Works great in conjunction with #2.
  2. Show real-world web sites breaking. If you can show that actual users are going to no longer visit X bank in Poland or Y shopping site in Canada then browsers will easily bend over backwards to fix the issue (unless it's Opera, in which case they may use their browser.js to force a site to work - but that's another story).
  3. Show a web standard that is being violated by not fixing this bug. If you're able to show that the W3C DOM specification is not implemented correctly because a certain bug is not fixed then a browser vendor should feel compelled to fix it. If not, this will make for great blog fodder.
  4. Show that not fixing the bug makes a browser incompatible with other browsers. If IE, Safari, and Opera all implement a specific feature or fix a specific bug then Firefox should be compelled to comply with the other implementations (as long as its not in contradiction with a specification). This is the hardest one to argue - but it becomes easier the more browsers that are on board.

If you can't prove any of those steps then you're probably just scratching your own itch anyway - and should lay off.


I want to show some representative examples of bugs that I've filed with different browser vendors.


Canvas arc() with radius of 0 throws exception: Calling the Canvas arc() method was throwing an exception. I provided a super-simple test case and pointed to the specification that they were in disagreement with. Was resolved the same day it was posted.

Out of Memory Error with .split("") due to large number of live objects: Provided a simple reduction with hosted web page, was fixed about 3 weeks later.


Huge Speed Drop in Array.prototype.sort: Showed a regression with a simple reduction. Included a bunch of very-useful Shark profiling data to help pinpoint the exact issue. Was fixed within a month.

Implement .children: Argued that Mozilla needed to implement the .children method (which was in every other major browser). A good debate led to its eventual inclusion (about 6 months later).

Internet Explorer 8

querySelectorAll NodeList Exception: Provided simple test case, was rejected due to 'lack of time':

At this time we do not plan on fixing this issue. We appreciate the report, but unfortunately we are at a stage where need to choose what we work on to maximize the value for customers and web developers.

So while they agree that it is an issue - they do not plan on fixing it. That means that I now get to complain about it!

HTMLElement.prototype.querySelectorAll doesn't exist: As it turns out this was because querySelectorAll only exists in standards-compliant pages (not in quirksmode). This is positively bizarre but I think I understand their rationale behind the decision. I suspect that this will bite a lot of people once IE 8 goes live, we'll see. I now know more about IE8 and am a better developer for it.

Google Chrome

for in loops don't occur in defined order: This was a compatibility issue (all other browsers behaved in a particular manner). I provided a simple test case. It was accidentally closed as WontFix (which caused confusion) but was actually fixed. I made a mistake here and actually filed this bug against Chrome when it should've been against V8 - here's the bug that dealt with the issue over there.

setTimeout(..., 0) fires too quickly: This was actually due to a structural change made by the Chrome team. Mike Belshe (the author of the change) personally emailed me to explain what happened. I became much more informed as a result and blogged about it.


(Opera does not provide an official public view for bug reports, that I know of.)

How to Test a Nightly Build

Before we get into the details of testing a nightly build of a browser I should probably answer the most common question: Why should I care about testing a nightly build of a browser? There are a couple reasons.

First, when filing a bug report you're going to need to determine if the bug you're submitting has already been fixed, or not. If it's already been fixed in a nightly then you don't need to worry about submitting it - the bug will be fixed in the next release. If the bug has not been resolved, though, then you should be sure to continue filing the bug.

Second, you should periodically test your site or library in the latest browser nightlies - to make sure that your code isn't going to break when the browser is released. How often you test is up to you - but the more frequently you test the more likely it is that your site or library won't hit a massive regression at some point. I think it's pretty safe to say that no developer likes finding out that there's a new browser version on the market that breaks their site.

Filing a bug for a nightly is just like filing any other bug. Provide a reduced test case and be sure to emphasize that a regression occurred. If you're testing frequently enough this should be sure to get the developers hopping into action.

Getting the Latest Nightly

Browser vendors provide a variety of techniques for getting the latest version of a browser. Some browsers release more frequently than others, as well (for example, Chrome updates multiple times a day, Firefox once a day, and Opera every couple weeks or so).


Mozilla provides nightly releases of Firefox. It can be installed, and used, alongside your existing copy of Firefox using Firefox Profiles. Once you download one nightly release it should update itself, automatically, every day.

Download: Firefox Nightly Release


WebKit nightlies are easy to install on OS X - they can live completely side-by-side with no profile details. However they do not update automatically. I use NightShift to make sure that my WebKit nightly is kept up to date (on OS X).

Doing a nightly install on Windows is much more cumbersome (it involves running some scripts and copying files around) but it works.

Download: WebKit/Safari Nightly Release

Internet Explorer

Internet Explorer installs are "a big deal" - they completely blow away any previously-installed copy of the browser. For this reason you should be sure to use some tricks to keep multiple copies of Internet Explorer installed on your system. There's one installer that can handle IE 6 (and older) and another one for taking care of IE 7. Once you have all those standalone versions installed you can feel safe downloading and installing IE 8.

IE 8 automatically updated from each beta release but it doesn't appear to do it any more. If you sign up for the Microsoft IE Beta Connect program you can get more recent builds to test against. Again, all of these builds will overwrite older versions of the current browser.

Download: IE 8 Betas, IE 8 Weekly Builds

Google Chrome

Google provides multiple builds per day (one for each revision). These builds can live side-by-side with one another but they do not update automatically. One user built an automatic update application that you can use to make that happen.

Download: Google Chrome Nightly Builds


Multiple versions of Opera can be installed side-by-side and they update automatically. They don't provide nightly builds (they come out every couple weeks, or so) but they should serve as a relatively-current example of the browser.

Download: Opera Desktop Team Blog (builds are posted here)

The importance of taking an active role in the future of web development cannot be overstated. Shifting from a passive position of hoping that other developers will be proactive about filing bugs or hoping that browser vendors will notice every possible regression to one of active diligence gives you an incredible amount of power. The minimal amount of work that you do to improve communication between the web community and browsers does volumes for helping to improve the quality of the entire web.

You should wear every bug that has gotten fixed, because of you, as a badge of honor: You've done your part to make the web a better place.

Пост № 245982

4х килобайтовый шутер.

идеальный openid

со всех сторон хорош openid, кроме одной. Она же — самый большой его недостаток. Проистекает этот минус из новизны технологии: пользователи привыкли писать в формочку логин и пароль, а понять, и уж тем более принять новое для них тяжкий труд. Для всех по разным причинам.

с этим пора бы уже бороться, но даже исследования ситуации были проведены только совсем недавно яхой и гуглом. Впрочем, может оказаться так, что мы, веб-разработчики, сможем миновать эту проблему по короткому пути. Конечно, решением окажется очередная технология. All hail Holy Science!

я уже немного писал о технологии Directed Identity:

если вы уже залогинены на гугле, на новом сервисе вам даже не нужно указывать свой емейл — достаточно кликнуть «использовать гугл/яндекс для входа»

но теперь я хочу ещё и показать её в действии. Форма логина в моём блоге переработана, чтобы лучшим образом демонстрировать прелесть решения. (Да, юзабилисты бы могли её улучшить, но это сравнительно быстрый набросок.)

итак, что видит неопытный пользователь, оказавшись на этой странице? Надписи «вход через Google» и «вход через Yandex», ещё и с фавиконами. Конечно, я нерепрезентативен, и не могу в полной мере представить, что творится в его голове, но подозреваю (и очень надеюсь :), что такая новизна вызовет в его голове максимум лёгкую заминку. И он радостно кликнет кнопку, и магия openid начнёт свою работу.

это самый простой вариант, который можно поставить прямо в обычной форме логина для массового пользователя, под полями емейла-пароля. Но через какое-то время эту технологию поддержат больше провайдеров, и кнопок на всех не напасёшься. Тут уже можно будет для менее популярных вариантов использовать выпадающий список — тоже с фавиконами. Главное — не забыть для самых гордых оставить поле свободного ввода, где можно указывать произвольные сайты : )

конечно, это решение можно ещё дорабатывать, наполнять всякими свисточками-колокольчиками, но базовое мегаудобство видно уже сейчас. А теперь внимание: если ваш сайт уже принимает openid, то от вас требуется всего ничего! Буквально пара простейших строк в шаблоне:

<form method="post" action="/login/openid">
    <input type="hidden" name="openid_identifier" 
        value="https://www.google.com/accounts/o8/id" />
    <input type="submit" value="Login via Google" />

вы просто один раз заполняете значение openid, и вашим пользователям больше не придётся об этом думать. Так сделайте же это прямо сейчас! : )

jQuery changeset 5985

Shared by arty
в prototype сейчас тоже работают над чем-то похожим

jQuery changeset 5985 (via). jQuery trunk has ditched browser sniffing in favour of feature testing, where a small suite of unit-test-like code blocks is used to detect whether a browser supports specific idioms. If the tests fail jQuery still makes assumptions about what the fix is, but it’s not hard to imagine the library eventually using code tests to ensure the fix will work as well.

From the Department of Badly Chosen Defaults

Shared by arty
img { -ms-interpolation-mode:bicubic; } для нормального масштабирования в ие

Alert reader Chris S. emailed me to point out this post by a developer at flickr about how to make IE scale images more smoothly. All you have to do is add

img { -ms-interpolation-mode:bicubic; }

to the stylesheet. It worked!

Note that all the other browsers use bicubic interpolation for scaling by default, because that’s the only thing that make sense, but IE requires a non-standard CSS extension. So, pictures on this site should be a little smoother for those of you determined to use Internet Explorer.

Happy Hannuka!

Need to hire a really great programmer? Want a job that doesn't drive you crazy? Visit the Joel on Software Job Board: Great software jobs, great people.

a farewell to verdana

в «типографских раскладках» есть куча unicode goodies, которыми очень приятно пользоваться. Но моя радость была неполна. Дело в том, что я собирался забыть, как о страшном сне, вид слов «стОит», «стоИт», и прочих с «ударением для бедных». Своё место по праву должен был занять юникодный символ ударения U+0301 COMBINING ACUTE ACCENT.

если вставить этот символ после буквы, он будет отрисован над ней. Так было бы, не вмешайся в дело Вердана! Это заслуженный, многими любимый шрифт, но у него есть особенность. Не знаю, почему, но знак ударения он рисует над следующим символом, а не над предыдущим. Особенно трагичный результат получается, если автор хочет поставить ударение на первую из двух гласных, как раз как в слове «стоит».

а вердану любят очень многие веб-разработчики. Поэтому на куче сайтов весь смысл использовать U+0301 теряется. Конечно, некоторые страницы можно доработать, например, в моём жж вердана отключена, но это капля в море. Поэтому в конце концов я решил откопать топор войны приём «это проблема мира, а не моя». И первое, с чего я начал — грохнул вердану из системы:

sudo rm /usr/share/fonts/truetype/msttcorefonts/Verdana*

пока что хуже стало только в Prizm, где у меня запущен RTM, потому что размер шрифта в призме не настраивается. В остальных местах у меня крупные шрифты, и разницы особо не заметно. Хотя с непривычки стало немного пикантнее ; )

жрецы программирования

Совсем недавно я понял, отчего многие программисты, использующие PHP, отличаются от программистов «в целом». Основой для моего понимания стали слова Руслана Косолапова: «Это PHP. Понять невозможно, только запомнить». А ведь действительно, это так. Объясню, почему.
Практически все, кто плотно работает с PHP, соглашаются, что язык вовсе не прост в изучении: если в большинстве языков надо понять принципы, заложенные в язык, а потом обращаться к документации по необходимости, то тут фокус не прокатывает: в документацию придётся смотреть практически всё время — потому, что логика не работает. Дело в том, что PHP имеет огромное, неимоверное количество функций, размазанных в глобальной области видимости. Функции эти писались в разное время, разными людьми, без чётких соглашений о том, как их называть, как организовывать приём параметров, как возвращать результаты. Очень и очень многое сложилось стихийно, исторически, а раз так сложилось, то переделке уже не подлежит. В рамках каждого расширения — свой стиль и своя логика. Область видимости, в которую импортируются функции из расширений, — глобальная, а глобального стандарта не было, нет, и уже очевидно, что не будет: слишком велик объём необходимой для этого работы.
PHP — это язык с историей, у него слоёв — как у древнего города. Он начался с набора скриптов на Perl для создания домашней странички, потом был переписан на C (несколько раз). Движок переписывался, а стихийно добавляющиеся функции оставались из соображений обратной совместимости почти неизменными, разве что увеличивали количество параметров. Но так, чтобы список параметров сократился, или, скажем, функция пропала — такого не было на моей памяти (это с 1998-го года). Кстати, порядок аргументов функций надо запоминать. Простой пример: если функциям поиска preg_match() и ereg() необходимо передавать сначала «что ищем», затем «в чём», а третьим, опциональным, параметром можно передать переменную для сохранения найденного, то функции strpos() — наоборот; оцените, кстати, разнородность и нелогичность названий функций как таковых). Что функция возвращает, и в какой ситуации — тоже надо запоминать. Та же strpos() вернёт false в случае, если ничего не найдено, и в документации особо подчёркнуто, что функция может вернуть и 0, то есть сравнивать возвращаемое значение и false надо с учётом типа, так как при проверке без типов целочисленный ноль сконвертируется в false.

Это всё была присказка для тех, кто не слишком в теме. А теперь пристегните ремни: начинается сказка.
Всё вышеописанное требует от программиста наряду с прочими навыками наличия ещё одного парадоксального умения: не пытаться обобщать накопленные знания. Лично мне всегда было проще понять или придумать правило, чем запомнить великое множество случаев, к которым оно подходит. В данном случае исключений из правила будет больше, чем случаев, в которых оно сработает.
Начать работать с PHP можно очень быстро (аккурат засчёт простого и местами удобного синтаксиса). Именно поэтому его и начинают учить новички, да ещё, как правило, параллельно с изучением какого-нибудь проекта. И начинается абсурд: люди изначально привыкают к работе с низкосортным кодом, доставшимся в наследство; а объём кода проектов чаще всего таков, что переписать правильно, по идее, можно, но… только при наличии большого опыта работы, наличии свободного времени, ну и так далее, — сиречь нереально. И плодят, делая свои первые шаги к мало-мальскому мастерству, очередные тонны кода, который будет приводить в ужас всех, пришедших следом.
Такова настройка Windows — там тоже нужно помнить многое. Правил мало, каждая менюшка — частный случай. Хотя вроде бы всё просто и наглядно, но вот лично мне проще прочитать толковую документацию без картинок и настроить нужный функционал в одном месте, чем с умным видом втыкать в книжку-раскраску для самых маленьких. Хотя начать можно просто и быстро, да.
Недавно я читал пост в ЖЖ, где в комментариях прошла идея сравнения эникейщиков Windows и жрецов из D&D. Процитирую: «В игровой системе D&D придумано такое интересное деление для характеристик мыслительных способностей пресонажа: на INT (интеллект) и WIS (мудрость). Для мага более существенен INT, для священника - WIS, хотя игровая суть примерно одна и та же - использование волшебства (что это, как не проекция работы “компьютерщика” с точки зрения среднего обывателя). Впрочем, игровая механика нам тут несущественна, но интересна сама классификация способов постижения мира — путем самостоятельного построения логических конструкций (INT) или путем накопления знаний (WIS)».
Это я к чему: в целом для программиста важнее развитые, «прокачанные» механизмы мышления, чем запоминания разнородных, не связанных друг с другом фактов. Но вот для программиста на PHP ситуация меняется с точностью до наоборот: важно помнить факты, не пытаясь понять. А я-то всё думаю, отчего святая война в проекте между программистами может разгореться из-за того, что один помнит, что кавычки разных типов обрабатываются с разной скоростью (скорость ничтожна, но на огромнейших циклах, невозможных в реальной жизни, становится заметной), а второй указывает на то, что на самом деле такого цикла не нужно делать практически нигде и никогда. Для первого это факт, и это следует постоянно учитывать. При этом он же не понимает, что проверять неопределённую переменную в том же цикле — это многократно большая трата ресурсов; что ошибку можно заэкранировать, но ошибка от этого не пропадёт; не понимает, зачем нужна независимость транзакций. Дело не в том, что один из них умнее, а другой глупее, нет. Это просто другой тип мышления, ориентированный на запоминание, а не на стремление собрать данные и проанализировать ситуацию с разных сторон. А сам PHP — как инструмент, как средство, как тема общения, — привлекает к себе людей в первую очередь «запоминательного», а не аналитического типа.
Жрецов программирования.

Open source / VirtualBox 2.1.0 и трансляция OpenGL вызовов

На прошлой неделе произошло событие, которое в принципе может быть затерто в истории софтостроения, но мне оно показалось интересным. Сейчас системы виртуализации развиваются маленькими, осторожными шажками, поэтому найти что-то интересное, или хотя бы значимое, отличие между версиями 2.х и 3.х или даже 4.х не всегда возможно.

Поэтому release notes на версию VirtualBox 2.1.0 я листал без особого интереса. Но за что зацепился глаз и заставил почитать повнимательнее, так это «Трансляцию OpenGL вызовов прямо в драйвер host машины».

А под катом как я тестировал эту функциональность

подозрительный чужой код

когда-то давно веб-разработчики захотели дать своим пользователям немножко свободы. Пусть, мол, они используют html для оформления своих текстов на нашем сайте. Некоторые плохие люди решили злоупотребить своей свободой, и так появился XSS. Разработчики пробовали от него защищаться, написали кучу библиотек, но их число, помноженное на число особенностей разных браузеров, достаточно велико, чтобы xss-дырки появлялись регулярно.

теперь веб-разработчики хотят большего. Теперь пользователям дадут в руки не только html, но и javascript. А это уже полный караул в плане безопасности. Нет, есть практически непробиваемый кроссдоменный барьер, но куча ифреймов на странице — это как-то неаккуратненько™, да и работает медленно.

проблемы возникают из-за того, что яваскрипт (да и любой другой язык, наверное) изначально не проектировался под разграничение полномочий исполняемого кода. Но, к счастью, он очень гибок, и теоретически можно попробовать пропатчить его прямо в браузере. Я пока знаю только об одной попытке добиться этого — Caja (читается «каха»).

«закахолить» (cajole) можно не всякий код, там много разных не очень приятных ограничений, но зато получившийся на выходе результат можно спокойно включать на свой сайт. По крайней мере, нам так говорят. Яваскрипт ведь реально очень гибкий, и куча его особенностей, помноженная на особенности браузеров и варианты caja-библиотек, скорее всего опять приведут нас к множественным уязвимостям.

тем не менее, команда разработчиков Yahoo решилась на это пойти. Я не разбирался в подробностях, но знаю, что их яваскриптеры с Дугласом Крокфордом во главе — параноики. А сейчас они используют Caja для сотен миллионов своих юзеров. Может и получится, посмотрим…

10 is the one

Shared by arty
лол: куча веб-разработчиков не задумались о том, что номер версии браузеров может быть длиннее одной цифры : )
это даже тупее, чем Y2K
опера, как обычно, первой принимает на себя

So we're busy preparing the major upgrade from 9.5x and 9.6x - and what's more obvious than calling it Opera 10? What's in a name, or a version number?

Apparently a lot of trouble.

As Andrew Gregory already noticed, we're the first browser ever to release with a two-digit version number. If websites assume that version numbers always have a one-letter "major" part and look for a single digit, they are going to "detect" Opera 1!

Since we released the first preview of Opera 10, we're seeing the bug reports come in. Web sites go belly up because of their bad sniffing. Some of them aren't even ashamed of it..

Thanks, Bank of America. Do you feel like it's 1995 again? Yeah, me too.

You'd think that with the intense development Microsoft has been lavishing on live.com they would have found somebody capable of writing a usable browser sniffer (or ideally a person clever enough to say "wait, we don't really need one - what if we just use feature detection instead?"). Think again..

..and for further evidence that their backend version detection is an odd piece of software engineering, read their cookies closely - Opera 9.62's request first, then Opera 10:
GET /mail/browsersupport.aspx 
Host: co109w.col109.mail.live.com 
User-Agent: Opera/9.62 (Windows NT 5.1; U; en) Presto/2.2.0 

Set-Cookie: BrowserSense=Win=1&Downlevel=0&WinIEOnly=0&Firefox=0&Opera=1&OperaVersion=9.2&Safari=0; domain=.live.com; path=/

GET /mail/browsersupport.aspx 
Host: co109w.col109.mail.live.com 
User-Agent: Opera/10.00 (Windows NT 5.1; U; en) Presto/2.2.0 

Set-Cookie: BrowserSense=Win=1&Downlevel=1&WinIEOnly=0&Firefox=0&Opera=1&OperaVersion=&Safari=0; domain=.live.com; path=/

Did you spot the missing version value? We really confused them by adding 0.37 to our previous value, didn't we?

Speaking of cookies, they are the main reason we added the feature that lets you hide Opera's identity. Back then in 1996 or so, some sites would do browser sniffing and send cookies only to known browsers. On the next page, if you didn't serve it cookies the site would say "hey, you don't support cookies so go away". What would Joseph Heller make of that, I wonder?

So, rewind to meet the catch-22 server, re-born at Bank South Australia:
GET /InternetBanking/ HTTP/1.1
User-Agent: Opera/9.62 (Windows NT 5.1; U; en) Presto/2.1.1
Host: ibanking.banksa.com.au

HTTP/1.1 200 OK
Set-Cookie: JSESSIONID=000019WTazsWAk-lB38OrmKD3kR:13l3ifhnq;Path=/
Set-Cookie: bhCookieSess=1;Path=/
Set-Cookie: bhCookiePerm=1;Expires=Sat, 20-Dec-2008 23:35:40 GMT;Path=/

..and Opera 10..:
GET /InternetBanking/ HTTP/1.1
User-Agent: Opera/10.00 (Windows NT 5.1; U; en) Presto/2.2.0
Host: ibanking.banksa.com.au

HTTP/1.1 200 OK
Content-Type: text/html;charset=ISO-8859-1
Content-Language: en-AU
Date: Thu, 18 Dec 2008 23:34:37 GMT
Connection: close

Um, I'm hungry. Where are your cookies? Predictably the next page looks like this:

This is probably just the beginning. :(

Will the web ever learn?

Skype / Оригинальный способ хранения изображений флагов

Поставил сегодня я новую бета версию Skype и заодно решил посмотреть старым добрым Restorator'ом какие ресурсы (картинки в частности) содержит 25 мегабайтный файл. И наткнулся на очень интересный способ хранения флагов стран:

Upd: Рисунок оригинальный, ничего не менял, только прозрачные области белым цветом залил.

Цитата #401793

Седня подумал о том, что если взять собирательный образ настоящего программера - лысина, борода, пузо, то получится собирательный образ настоящего байкера.

Three Flavors of Net Neutrality

When the Wall Street Journal claimed on Monday that Google was secretly backtracking on its net neutrality position, commentators were properly skeptical. Tim Lee (among others) argued that the Journal misunderstood what net neutrality means, and others pointed out gaps in the Journal's reasoning -- not to mention that the underlying claim about Google's actions was based on nonpublic documents.

Part of the difficulty in this debate is that "net neutrality" can mean different things to different people. At least three flavors of "net neutrality" are identifiable among the Journal's critics.

Net Neutrality as End-to-End Design: The first perspective sees neutrality as an engineering principle, akin to the end-to-end principle, saying that the network's job is to carry the traffic it is paid to carry, and decisions about protocols and priorities should be made by endpoint systems. As Tim Lee puts it, "Network neutrality is a technical principle about the configuration of Internet routers."

Net Neutrality as Nonexclusionary Business Practices: The second perspective see neutrality as an economic principle, saying that network providers should not offer deals to one content provider unless they offer the same deal to all providers. Larry Lessig takes this position in his initial response to the journal: "The zero discriminatory surcharge rules [which Lessig supports] are just that -- rules against discriminatory surcharges -- charging Google something different from what a network charges iFilm. The regulation I call for is a 'MFN' requirement -- that everyone has the right to the rates of the most favored nation."

Net Neutrality as Content Nondiscrimination: The third perspective sees neutrality as a free speech principle, saying that network providers should not discriminate among messages based on their content. We see less of this in the response to the Journal piece, though there are whiffs of it.

There are surely more perspectives, but these are the three I see most often. Feel free to offer alternatives in the comments.

To be clear, none of this is meant to suggest that critics of the Journal piece are wrong. If Tim says that Google's plans don't violate Definition A of net neutrality, and Larry says that those same plans don't violate Definition B of net neutrality, Tim and Larry may both be right. Indeed, based on what little is known about Google's plans, they may well be net-neutral under any reasonable definition. Or not, if we fill in differently the details missing from the public reporting.

Which bring me to my biggest disappointment with the Journal story. The Journal said it had documents describing Google's plans. Instead of writing an actually informative story, saying "Google is planning to do X", the Journal instead wrote a gotcha story, saying "Google is planning to do some unspecified but embarrassing thing". The Journal can do first-class reporting, when it wants to. That's what it should have done here.

Vodafone uses Opera to push for open standards

Vodafone's new Widget Manager runs on Opera and open standards instead of proprietary platforms like Nokia's Widsets. The reason is simple:

[Widsets] is a Java platform, so it’s not open. Widget Manager is built on Opera, so it’s faster and easier to write for. It uses open standards.

Easier to write, shorter time to market. This basically echoes Opera's position. Using open standards makes it faster and easier to develop applications. Opera is pushing for widgets based on open standard, and Vodafone seems to agree that this is a good thing.

So now both Vodafone and T-Mobile are going for Opera's widget solution rather than competing technologies that are proprietary and more difficult and time-consuming to work with.

Linux для всех / Плагин для быстрой смены кодировки открытого файла в Gedit

В Gedit есть возможность выбирать кодировку файла при его открытии. И при открытии файлов вкодировке отличной от системной в Gedit, возникают проблемы кракозябры. Вроде бы есть и автоопределение кодировки, но оно у меня ни разу не работало :-(.
Читать дальше →

Django Framework / South — новый клёвый syncdb

Я совсем недавно начал работать с Django и меня практически сразу же взбесила ущербная команда syncdb, которая ничего толком не синхронизирует, умеет лишь создавать таблицы для новых моделей.

А добавление или удаление полей в уже существующие модели превращается в настоящий pain in ass — приходится «подсматривать» за тем, как ORM создала бы таблицы заново (manage.py sqlall) и вручную делать ALTER TABLE для изменившихся столбцов таблиц.

То есть, ORM в Django так или иначе предполагает активный трах с SQL shell, потому что в процессе прототипирования эти поля в моделях изменяются просто пачками.

Погуглив, я нашел несколько способов...

youtube минус flash

флешовые видеоплееры давно раздражают меня тормозами и глюками. Долгое время я боролся с ними, скачивая ролики на диск, чтобы комфортно смотреть их любым плеером на выбор. Сейчас придумал способ получше, но как обычно, был не первым : )

есть уже много юзерскриптов, которые заменяют флешовый видеоплеер обычным системным (например, mplayer), но я не могу найти среди них такого, который работает в опере и не только на самом сайте ютюба. Основная проблема в том, что для скачивания видео нужен ключ, который есть только там, а делать кроссдоменные запросы запрещает безопасность. К счастью, гугл одной рукой отбирает, а другой даёт нам AppEngine, который идеально подходит для задач такого рода ; )

поэтому предлагаю yet another userscript для ютюб-видео. Заодно можно добавить в адблок правило http://*youtube.com/v/*, чтобы флеш даже не инициализировался лишний раз. Как обычно, всё это AS IS, за глюки автор ответственности не несёт : )

Extending jQuery's selector capabilities

Extending jQuery’s selector capabilities. I already knew this was possible, but the examples James Padolsey provides are eye-opening—I especially like his clever :data selector extension which lets you write CSS selectors that query against jQuery’s custom “data” DOM element storage in a manner similar to CSS2 attribute selectors.

Net Applications again: Opera vs. Chrome - actual numbers vs. claimed market share

Now that Google have announced that Chrome has reached 10 million users worldwide and our quarterly reports report the number of active Opera desktop users, we can actually compare these numbers to various browser stats.

Since I've been writing a lot about Net Applications lately, let's take a look at how they are doing. According to them, Opera's market share is 0.71%, and Chrome is at 0.83% for November.

If the numbers reported by Chrome and ourselves are accurate, Opera has three times more users than Google worldwide. However, Net Applications reports that Chrome actually has a higher market share.

Food for thought.

Congratulations to Google, by the way, for the official release of Chrome!

markdown под рукой — в glipper

я люблю маркдаун. Другие системы разметки текста тоже неплохи, но почему-то я прикипел именно к этой. К сожалению, пока что у неё почти нет поддержки. Нет, конечно, я встроил маркдаун в свой блог, и знаю еще несколько дневников, которые его поддерживают, но этого очень мало. С другой стороны, почти везде есть поддержка html. Вот если бы всегда иметь возможность написать текст в markdown, и тут же превратить его в html…

какой инструмент всегда под рукой при работе с текстом? Буфер обмена. Лучше даже «clipboard manager» — все они позволяют как минимум хранить несколько объектов. В гноме он называется Glipper. И, что очень удачно, поддерживает плагины на питоне.

в общем, я решил, что удобнее всего будет выделить маркдаун-текст, нажать хоткей, и вставить html-текст. И сделал это за полчаса. All hail python & FOSS! : )

простота меня настолько радует, что я даже не буду выкладывать это куда-то отдельным файлом, а приведу прямо здесь. Две функции и описание — вот как это должно быть.

$ cat /usr/share/glipper/plugins/markdown.py
import glipper
import markdown2
import gtk
from gettext import gettext as _

def init():
   menu_item = gtk.MenuItem(_("Markdown"))
   menu_item.connect("activate", commandActivated)

def commandActivated(menu):
   item = glipper.get_history_item(0)
   item = markdown2.markdown(item)
   glipper.set_history_item(0, item)

def info():
   info = {"Name": _("Apply markdown"),
      "Description": _("Activate plugin to convert last history item to html using markdown"),
      "Preferences": False}
   return info

как линукс проигрывает

я недавно шарил ссылку на интересную мысль о ещё одной причине низкой популярности линукса. И это отнюдь не его сложность. Идея в том, что эникейщики вложили немалую часть своей жизни в изучение винды, и переход других людей на открытый софт их заметно огорчает. В принципе, их можно понять: любой расстроится от обесцененных инвестиций.

с другой стороны, этот пост был в большей степени догадкой. Я не мог утверждать, что так оно и есть. Но вот теперь могу. По крайней мере про африку : ) Может быть, люди там более простодушны и открыты, но те «админы» явно сообщали, что недовольны своей ненужностью из-за чрезмерной простоты линукса:

However, installation of Kunnafonix was resisted by many of the local organizations they had to work with. The local "computer support person" resented a solution that was so easy to use that it undermined the power and prestige they received by being the person to consult when a Windows computer had problems.

via Simon Willison

ps: не знаю насчёт всей Почты России, но ближайшее ко мне отделение на своих компьютерах, в том числе и сдаваемых в аренду, содержит OpenOffice. Правда, под виндой, но начинается с малого : )

lxml: an underappreciated web scraping library

lxml: an underappreciated web scraping library. I just wish I could get the wretched thing to install on OS X Leopard without resorting to MacPorts.

серверные события: забавный глюк

вообще поддержка серверных событий в опере до сих пор находится в состоянии proof of concept. Впрочем, это и хорошо, потому что спека с тех пор менялась неоднократно, а иметь одну старую версию (и потом вторую — окончательную) намного лучше, чем разбираться с зоопарком. Всё равно в других браузерах только ещё патчи готовятся.

однако использовать их хочется уже сейчас. В процессе использования нашёл и зарепортил забавный глюк: если элемент создан средствами DOM, событие на нём срабатывает дважды

use Perl or die;

iToday.ru - Герман Клименко - "Я планирую полностью поменять модель продажи рекламы в Интернете"

Язык программирования Python / Сила и красота декораторов

Одним из самых сложных для понимания и осознания элементов языка является декоратор, хотя по сути это очень простая вещь, доступная для понимания даже начинающему программисту. Новых Эверестов я не открываю, а лишь предлагаю краткий обзор возможностей и несколько типичных примеров использования. Этакий короткий экскурс в метапрограммирование на питоне.

Upd 1: изменил несколько категоричное утверждение о несходстве паттерна Декоратор и одноимённой языковой конструкции на более мягкое.

Читать дальше →

Could VC be a Casualty of the Recession?

javascript-фрики атакуют : )

год назад я удивлялся, как люди создают себе сложности, но сегодняшний перл круче всех:

nodes = doc['getElementsByTagName']('head')[0]

а о выборе имени _ для переменной можно вообще не говорить % )

update: оказывается, автор — Николай Мациевский, с которым мы вместе делали доклад об оптимизации. Неудивительно, что сейчас это он тоже написал для скорости. Впрочем, его результаты, видимо, перепутались, потому что запись через точку всё-таки быстрее.

firefox в засаде

интересно, это только в моём линуксе фф иногда решает «что-то скучно здесь стало», и за полминуты съедает два гига памяти? Подозреваю, что флеш тут тоже замешан, но уверенности нет.

CDATA %text

В спецификации html4 значение для alt тега img представляет собой %text, а alt для input тип CDATA. Но текст в общем и есть CDATA. В чем разница? Есть какие-то дополнительные ограничения на %text или что? Я не нашел ничего про это.

яваскрипт-магия в каментах

Internet explorer mystery #1376. IE executes function definitions inside an “if (0)” block. That frightens me.

Придумал неполиткорректную иконку для Advanced Settings: простреленая нога

Opera Mini в Москве популярнее FF3

В Рунете тем временем происходит невидимая революция: мобильные браузеры — а именно, Опера Мини — захватила уже весьма ощутимую долю рынка.

В Москве картина ещё более впечатляет:

Можно было считать это глюком Liveinternet, но статистика Mail.ru показывает схожие цифры.

Peer-to-Peer / µTorrent переходит на UDP-протокол

На форуме разработчиков клиента µTorrent появилось сообщение, что новая альфа-версия этого популярного торрент-клиента µTorrent 1.9 build 13485 поддерживает работу в режиме uTP (UDP torrenting). Более того, такой режим будет стоять по умолчанию. Другими словами, передача файлов в торрент-сетях (а это более 50% мирового трафика) может перейти с протокола TCP на протокол UDP. Для торрентов пинг снижается с 2000 мс до 50-100 мс (результаты тестирования см. в PDF), это хорошо. Но чем это грозит для качества работы VoIP, многопользовательских игр и других приложений, которые используют UDP для передачи данных (и в данный момент потребляют не более 2% мирового трафика) — сложно даже предположить.

В данный момент телекомы эффективно угнетают торрент-трафик, освобождая полосу в пиковые часы. Если торренты перейдёт на UDP, то телекомы не смогут делать это на существующем оборудовании. По крайней мере, существующая практика пакетной атаки типа TCP RST, которую использует Comcast и другие провайдеры, станет полностью бесполезной.

Первые тестеры, которые уже проверили работу новой альфа-версии µTorrent, рапортуют о том, что на них не действует шейпинг в сети провайдера Bell Canada. Использовать эту раннюю версию, однако, не советуем, потому что в ней ещё много серьёзных багов.
Читать дальше →

Amazon SimpleDB a complete flop?

Amazon SimpleDB a complete flop?. Terry asks if anyone is actually using SimpleDB (related Google searches indicate not, and I’ve personally not heard of anyone using it despite plenty of usage of S3 and EC2). One factor might be that lock-in to EC2 and S3 is pretty small, but if you rely on SimpleDB you’ll need to rewrite your entire application to escape.

количество var на область видимости

одна из идей, которые продвигает Дуглас Крокфорд (и, следовательно, его JSLint) — что на одну область видимости aka scope должно приходиться максимум одно ключевое слово var. Узнав об этом, я некоторое время пытался следовать рекомендации, а потом даже задумал написать об этом пост. Но поиск ссылок по теме довольно быстро привёл меня к опровержению: по спеке яваскрипта количество var в scope не имеет значения, и браузерам действительно пофиг.

← предыдущий месяц