标准的Firefox

某个我常去的论坛上,时不时会出现贴子布局混乱的问题,如下图(因为原贴太长,所以PS过以减小图片面积):

混乱的网页布局

混乱的网页布局

很明显的,左上角出现的“–>”很好的暗示了我们,HTML中有点乱套了。而且这也常常是网站系统可能存在XSS漏洞的最初现象之一,我不邪恶,不过担心别人会邪恶,所以打算把问题原因找出来,告诉网站管理员。

长期的实践中,我曾对这个问题总结过一个规律:这个问题只在Firefox中出现,并且会乱掉的贴子多半是因为某一个特定ID的人参与了讨论,开始混乱的位置常常是在那个ID的人的签名档往上一点的位置。

今天为了分析解决这个问题,你会怎么推理?我的推理是:由于签名档允许部分HTML,一些不规范的HTML标签导致了页面混乱。

于是去查看HTML源文件,原始文件太长,所以这里就示意一下:

<div>
<!-- Blah blah blah <br />
-------------- <br />
Foo bar Foo bar
-->
Blah blah blah <br />
-------------- <br />
Foo bar Foo bar
</div>
<div style="maxHeightIE: 160px;">
My signautre. My signautre. My signautre. My signautre. My signautre.
</div>

是的,推理错了。显而易见的,签名档中并没有问题,而且HTML代码似乎也没有什么异常的地方。把这段HTML放到一个新的空白网页中,显示也一切正常,没有发生混乱。

也许是网页中有一些不可见的字符,而且复制粘贴后就没有了?Emacs帮我证明了不可见字符这一点,这个网页在我的Linux平台上是以LF字 符做为换行的,但那个贴子内容中的换行符却是Windows中的CR LF。于是我把CR字符都删掉,问题依旧。难道还有更神秘的不可见字符在搞鬼?用二进制文件编辑器查看这个文件,一切正常。

再分析一下,在网页上出现混乱的起始点是–>符号,那看来是在那段注释中就已经出现问题了。用Firefox自带的查看源代码的功能,可以看到,它只把注释的前两行识别成为注释,标记成绿色,从Foo bar那行开始,就变成正常的HTML标签的颜色了。

为什么Firefox会错误的识别HTML注释标签的结尾?难道因为这个文件编码有问题(原始文件中是有中文的,例子中只写了英文字符)?(大家还记得Windows记事本对待联通和移动的不同态度吧) 把网页由GBK编码重存为UTF-8编码,问题依然。

没招了,借助神奇的Google,换了好几次关键词之后,终于用“Firefox comment bug”这个关键词找到了有用的信息

简单的说,HTML4规 范中,注释的起始标签是<!,注释的起始和结束符号是–,注释的结束标签是>。当然,这是一个很严格的形式化的定义,但这跟我们通常想象中 的注释由<!–开始,以–>结束是不一样的。因为HTML4规定,结束符号–和结束标签>间可以有空格隔开,也就是说,并不要求 –和>连在一起写才表示注释结束。规范建议在注释中不要出现两个或以上“-”出现的情况。

规范中没有说结束符号–和结束标签>之间除了空格以外可不可以有别的字符出现,Firefox很激进把它定义为允许出现,所以就带来了我们所看到的问题。

事情还没完,那为什么把这段代码单独贴成一个HTML文件测试就没有问题呢?因为没有指定DOCTYPE时,Firefox不会按HTML4的规范去解析。如果你在测试文件开头加上HTML4的DOCTYPE就可以重现这个问题了:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">

还没完,那为什么这个问问往往出现在某个特定ID参与过的贴子上呢?因为那个人不喜欢用论坛的“引用”功能,他喜欢复制前一个人说过的话,用———隔开,下面写回复。或者就是用———来分隔他的贴子正文的几段内容。

为什么那个BBS系统中要把贴子的内容输出两遍,其中一遍是在注释中呢?不知道。有一种可能性是开发者还不熟悉网页后台系统的开发,他总是习惯用HTML中的注释语法去注释后台他不想要的代码。这种做法基本上是错误的,但犯这样错误的人绝不在少数。

继续,虽然Firefox这样做没有违背规范,但多少有点违背常识,为什么它不修复这个问题呢?这是因为它要兼顾SGML的解析——在那里“–”有着很重要功能。不过由于HTML5中对注释的语法做了更严密的规定,Mozilla说,他们准备在后续的版本中修复这个问题。

最后,Firefox这个问题会不会带来原本可能不存在的XSS攻击?应该说可能性是有的,但主要问题还是会出在网站开发者的身上。比如你在后台调试时,输出了未转意的用户输入内容,并用HTML的注释注释掉了,你以为是安全的,但由于这个问题的存在,带来了XSS攻击的可能性。

这个故事还告诉我们一些道理,不写了。因为我已经把分析/走弯路的过程写得很详细了,那些道理都是简单易见好理解的,只是常常我们做得不太好。

在Debian Squeeze下安装Dropbox

听说Dropbox这个在线存储服务商很久了,不过一直没有去用过,因为我一直认为在线文件存储在ADSL小水管上是一个不靠谱的服务——上传速度太慢了。

这几天我订阅的若干个RSS上都不约而同的出现一些有关Dropbox的文章,有使用技巧的、有商业模式分析的、还有创业经历的等等。病毒式、口碑式的营销是Dropbox取得当前成功的一个重要因素。好吧,我承认我被这个“病毒”传染了,现在正在继续放毒,文章开头的Dropbox的链接是我的推荐注册链接,如果你通过它注册,你我都可以获得250M的额外存储空间。

Dropbox能迅速感染我的主要原因还是在于它的体验做的还是不错的,整个产品与操作系统的集成做得不错,使用起来非常自然,性能也远比想像中的要好。不过如果要在Debian Testing (Squeeze)上获得这样的体验,还是需要花一点功夫,因为Dropbox提供的Linux deb安装包只有给Ubuntu提供的版本,在Debian上安装会遇到依赖关系的问题:

nautilus-dropbox depends on libnautilus-extension1 (>= 1:2.22.2); however:
Version of libnautilus-extension1 on system is 2.30.1-1.

看上去只是版本号上的一点点小问题,可以直接强制安装:

sudo dpkg -i --ignore-depends=libnautilus-extension1 nautilus-dropbox_0.6.2_i386.deb

后果就是aptitude或者Synaptic都会发现存在broken的依赖关系,然后系统的包管理就不能正常工作了:不能安装别的包、不能升级……

搜索后找到了一个简单的解决方案,适合解决类似的deb依赖关系的问题(Debian/Ubuntu都适用):编辑/var/lib/dpkg/status文件,在里面找到存在依赖关系问题的包所在的位置,编辑它的Depends后面的项,改成一个可以被满足的版本号或干脆把无法满足的依赖项删除。在本例中,可以把“libnautilus-extension1 (>= 1:2.22.2),”改成“libnautilus-extension1 (>= 2.22.2),”或者干脆删除它。

这个方法很有效也很暴力,请确认知道自己在做什么并仅在必要、合理的时候使用这个方法。在大部分的情况下,也许自己重新编译生成一个适合自己的安装包是更正确安全的做法。

最后分享一下非常重要的几个小技巧:

1. Dropbox的Public文件夹文件外链的功能在国内不能正常使用,解决方案很简单:把生成的外链URL中协议由http改成https就可以了。

2. 在Linux下,可以用软链接把不属于Dropbox文件夹内的文件同步到Dropbox,但注意尽量只使用文件夹的软链接而不要对文件做链接,因为Dropbox在把文件同步回来的时候可能会把软链接变成普通文件,导致实际的文件不同步。

3. 在Windows的NTFS分区下,可以用Junction或mklink(Windows 7)把文件夹做链接,实现任意文件的同步,但要记得与Linux不同的是:只能把Dropbox文件夹内的文件夹建链接到外面,而不能把外面的文件夹链到Dropbox文件夹内,不然同步只会做一次,以后文件再变化就不会再同步了。

更多技巧可以参考:Dropbox免费网盘高级使用技巧

ssh-keygen这个扯蛋的网站

无意中看到www.sshkeygen.com这个网站(故意不做成超链),先感叹了一下现在真是什么事情都可以放到“云端”完成,然后就意识到这里面的问题了。

ssh-keygen是*nix系统中用于生成SSH登录用的密钥对的命令,很多公共的服务器出于安全考虑都要求用密钥对代替密码来登录系统。然而这种方式对于很多人来说是比较陌生的,如果想借助于搜索引擎来解决这个问题,就很可能上了这个网站的当。在线生成密钥对,这就意味着你的密钥已经被这个第三方的“在线”网站所知晓了,私钥泄露,那还有什么“密”可言呢?

仔细看看这个网站上的遣词造句,还颇有一点专业的味道。不过它故意让你多输入了用户名、单位、域名、IP这些生成SSH密钥对根本不需要的信息,显然是别有用心啊。如果再看看它的About的页面,有些看似友好的TO-DO功能改进,实际上更具险恶用心,比如这个:implement key installation via web interface。

简单查了一下,现在好像还没有在线生成GPG密钥对的钓鱼网站,估计因为这个相对SSH密钥来说比较无利可图吧。puttygen(Windows下一个常用的用于生成SSH密钥对的软件)相关的域名也还没有人注册,这个想上去应该比sshkeygen对小白们更有效果啊,有识之士应该抓紧去注册,做一个在线的puttygen系统……

做为一个Best Practice,永远只在本机生成密钥对,并充分保管好自己的私钥。如果非要在公共主机上使用密钥对,一定得给私钥加上一个强劲的Passphrase。把私钥文件设成0600的权限是必须的,但是是没有用的,因为每台服务器的背后都有一个名叫root的“邪恶”帐号。

旧金山印象-公共交通

作为一个合格的铁路、地铁双料爱好者,美国之行很重要的一个组成部分是体验当地的公共交通。虽然说美国是一个没车寸步难行的地方,但网上说旧金山市的公共交通还是比较发达的,这倒也增加了我的信心。

首先体验的是轨道交通,BART。BART是Bay Area Rapid Transit的缩写,也就是湾区快速运输的意思。从旧金山机场出来就可以看到换乘BART的导向标识,不怕迷路,不过买票的时候会有一些不习惯,因为它采用的是先投币后选择票价的方式。与国内地铁不同的是,它在购票时并不是选择目的地,而是可以打印出任意你所指定面值的磁条卡。如果在出站的时候票中还有余额,出站闸机会把票还给你。下次还可以继续使用,也可以继续往票中充值,不过如果是给车票充值,自动售票机会给你打印出一张新的车票。

BART的旧金山机场站有4个站台,不同站台会始发开往不同方向的列车。站台上的LED显示屏并不会一直显示车次的信息,倒是一直在翻滚着显示各种安全告示和动态新闻,所以还是要看注意看清楚自己应该在哪个站台候车。我的目的是市中心的Powell St.所以应该选择开往Pittsburg/Bay Point的方向的列车。

BART列车的发车间隔在15-20分钟左右,如果没有卡着点,还真是要多等一些时间。从机场到Powell St.有11站,大约需要30分钟,票价是$8.10。跟国内的地铁系统来比,实在是一个天价。

列车采用三轨供电制式,车况一般,车厢内的照明也比较昏暗,车站更是简陋无比,很多车站都像是无人值守的。车上座位很多,人很少,所以平峰的时候基本上是没有人站着的。

下午去伯克利大学时又一次体验了BART,而且中途还在12th St.进行了一次换乘,同台换乘非常方便。而且很重要的一点是,无论是BART,还是后面乘座的CalTrain或Muni,它们都有一个叫作Timed Transfer的机制,也就是说某些车次的列车是设计好卡着点让你换乘的,你可以从一列车上下来直接上另一列车继续旅行,基本上不会因为换乘而有过多的等待时间。

BART系统不允许拍照,作为一个老实人,我就什么照片也没拍。

周二下午要去一次公司,需要搭乘CalTrain,CalTrain可以看成是城际铁路,平时大约15-20分钟一班,周末则差不多1小时才有一班车。列车采用内燃电传动的机车牵引,大部分是客车都是双层客车,部分客车车厢下层是用于做为自行车车厢的。列车按停站不同分为3个等级,从多到少分为Local, Limited-stop和Baby Bullet三种。最快的Baby Bullet可以保证从旧金山到San Jose的旅途控制在1小时以内,而Local则常常需要90分钟,所有列车的最高时速都在127km/h左右。

CalTrain的计价方式采用分区计价,跟国内的地铁倒是比较相似。同样采用自动售票,票面是小磁卡。车站没有闸机也没有人检票,车上也只是偶而会有列车员查票,所以一切靠自觉。大部分CalTrain的车站也是很简陋的,规模基本上可以类比于国内某些城市的BRT车站。从旧金山到我的目的地Moutain View是跨了3个区间,距离差不多是机场到市区的不到两倍,票价$6,相比BART来说,是便宜了很多。

CalTrain的乘坐体验也很一般,有时候会很颠簸,实在不能跟中国的火车相提并论。工作日平峰时段人也很少,一节车厢能有10来人就不错了。

CalTrain列车到达Moutain View车站

CalTrain列车到达Moutain View车站

如果说BART和CalTrain不是一般观光客所首选的交通工具的话,旧金山的Cable Car,也就是有轨电车,或者叫叮当车,就是很多人想体验的交通方式了。叮当车最热门的线路就是从Powell St.到Hyde St.的线路,它可以把游客从市中心途经中国城和九曲花街,一路“翻山越岭”,送到渔人码头。

Cable Car很有历史,所以很多东西也很传统。在Powell St.或Mason St.等终点站,都可以看到一个大圆盘,车子开到上面,再用人力把它转动180度,实现车辆的调头。车子的速度也非常慢,不过做为观光使用,还真是很合适。尤其因为旧金山城市地型本来就起伏不平,坐在叮当车上,看它慢慢的爬上陡坡又冲下街道,还有很有一番情趣的。一辆叮当车很小,只能乘坐20来人,还可以在车外面悬挂10来个人,挂在车外看风景,更有一番风味。

叮当车单程票价$5.00,不过在Powell St.的起点站可以买公交车通票,一日票$13.00,三日票$20.00就可以在指定时限内不限次的乘坐叮当车和Muni公交车。三日票还有个不错的用途是可以用来在Ghirardelli购买正价巧克力时享受9折的优惠,Ghirardelli是旧金山最富盛名的巧克力品牌。不同时间购买的三日票可能会提供不同的Coupon,只是我那张正好是Ghirardelli的巧克力券。

旧金山的叮当车

旧金山的叮当车

包括叮当车在内的旧金山市公共交通,是由市政交通局(SF Municipal Transportation Agency)来运营的,标志就是Muni。Muni公交车票价$2.00,在90分钟内可以免费换乘。相比其它公共交通,Muni公交车车况大都还不错,车厢很大也很明亮,进站时还会放低底盘方便行动不便的人上下车。

很多公交站名都是以相交的两条的路的名字来命名的,所以很清晰,不太会错过站。如果下车,最好提前拉动侧窗上面的绳索,通知司机需要下车。车上的站名报站是英语的,但当有老人上车时,会用英语、粤语和(可能是)西班牙语三种语言提醒乘客把车前部的座位让给老人和行动不便的人。

旧金山印象-走马观花(3)

我写连载向来虎头蛇尾,又拖了有一个月了,赶快把这个连载的最后两篇写了吧,不然又是烂尾楼了。

Picasa Web相册这几天算是被彻底和谐掉了,正在考虑迁移方案。不过这篇文章中还是只少量贴图,免得我的Blog变成一个“图多杀猫”的地方。

中国城

要不是受人之托要去中国城买东西,如果在旧金山观光,个人认为中国城不去也罢。在旧金山华人的比例本来就非常高,商场、景点、街头处处可以遇见华人。

本来想在Powell St.搭叮当车去中国城,却发现周末叮当车的客流远远大于平时,排队很长。为了节省时间,就直接走去中国城吧。虽然距离不远,但却是连续的上坡路段,很累。

走在中国城的街头,感觉大概跟走在香港街头比较接近。满耳朵都是比英语还难听懂的粤语。在中国城街头,有不少叫卖蔬菜或水果的商店或市场,这点绝对是在中国城以外的街头难以看到的,很有中国味。

通常都是空空荡荡的Mumi公交车,在中国城的路段也常常可以坐到客满甚至于有人站着。选择坐公交车也许跟收入有关系,但很大程度上也许也还是更跟人们的习惯有关吧。

九曲花街

离开中国城,重新搭上叮当车,拐几个弯就到了旧金山著名的Lombard Street,常常被翻译成九曲花街。

九曲花街是Lombard Street夹在Hyde St.和Leavenworth St.中间的那一段,为自西向东的下坡单行道,坡道达到27度,所以只能是修成弯弯曲曲的形状,以便把坡度降为16度左右。

3月初显然还没有到百花绽放的最佳时间,所以整条九曲花街上只有一片片的绿色,相比鲜花盛开的时候来说显得单调了不少。

九曲花街,从东向西看

九曲花街,从东向西看

斯坦福大学

下午搭乘城际列车CalTrain,到达Palo Alto,也就是斯坦福大学所在的地方。

相比连大门都找不到的伯克利,斯坦福大学明显更有大学的气质。从Palo Alto车站下来,沿着Palm Dr直行就可以到达斯坦福的大门。Palm Dr沿路是两排很有意境的大树,而斯坦福门口的那片翠绿的大草地更是让人流连忘返。

斯坦福大学最著名的建筑,应该就算是古老的教堂和胡夫塔了。胡夫塔高87米,1941年斯坦福建校50周年时落成,是胡夫学院的一部分,它是由美国第31任总统胡夫所设立的。

斯坦福的校园相当的紧凑整洁,建筑风格也比较统一,不像伯克利那样是个大杂烩。校园里有个小土坡,上面有一潭水,如果换个好听的说法,就是“校园依山傍水”。

斯坦福大学教堂和胡夫塔

斯坦福大学教堂和胡夫塔

17英里

离开美国前的最后一天,有幸搭同事的车去位于加州Pebble海滩的太平洋海岸线17英里景区观光。在长约17英里的观光线路中,有一大半都是沿着西海岸线在走。那里风景优美,聚集着不少名人的豪宅。

17英里的游览线路中,包括了大约21景点。其中最著名的,应该属于那棵独自矗立在悬崖上的“孤独的柏树”(The Lone Cypress),它在这个景区的地位,可以相当于迎客松之于黄山。唯一不同的是每天有无数人排着队跟迎客松合影,而在这里,游客明显要少了很多很多。

除了柏树,其它很多景点也很有特色。在“鸟石”,可以看到很多各式的海鸟和成群的海狮,那里还有遍地跑来跑去松鼠们。在“鬼树”可以看到很多形状怪异的树干。在“Fanshell Overlook”,在春季可以看到成群归来哺育小宝宝的海豹。

最后的Pebble海滩,更是一个风景优美、观光休闲腐败一条龙的最佳去处,闻名世界的Pebble海滩高尔夫场就在那里。

孤独的柏树

孤独的柏树

离开17英里景区,去美丽的海滨小城卡迈尔用美食填饱肚子,返回旧金山国际机场,结束了美国之行。