2007年01月 的存档

给URL中的数字加1的JavaScript

一直都在想,如果有一个Firefox扩展,可以在工具栏增加一个按钮,点击一下就可以把当前页面的URL中的数字加1,自动打开下一个页面,那该是多好呀。不过,一直忙,没有抽空去找这样的Firefox扩展。

今天突发奇想,觉得可以用JavaScript做这件事情。没研究过JavaScript,靠着一点C++的底子写了一小段JavaScript代码。这段js可以放进Firefox的书签或者IE的收藏夹,点击它一下就可以打开当前URL的下一个地址。(也就是把URL中的数字加一)比如,当前页面的地址是"http://yskin.net/1.html",则点击页面后自动打开"http://yskin.net/2.html"。哈哈,我也会写JavaScript啦,bingo

所有WordPress架设的Blog,不论是否使用了永久链接,都可以通过"http://yskin.net/?p=1"这样的方式进行访问。另外,如果想一页一页的看,可以使用"http://yskin.net/?paged=1"这样的地址,依次加下去,就可以10篇10篇地看完所有文章了。所以,如果想遍历一个Blog的所有文件,用这个JavaScript最合适了。

随手打开抓虾,找了里面添加链接的代码,弄了下面这个东西,很方便吧。

如果你的浏览器是IE,右键点击下面的按钮,选择“添加到收藏夹”,忽略弹出的安全提示,接着选择存到“链接”目录,点击确定。
如果你的浏览器是FireFox(握手握手),把这个按钮拖到浏览器的工具栏中即可。
Next

Firefox 1.5.0.6和IE6 SP2下测试通过。

Update:升级,1.1,现在可以正确处理数字前面包含"0"的URL。

Update2:希望各位使用者到网站来右键添加链接,而不要直接在feed里添加。我倒不是为了访问量,只是刚刚发现在Bloglines里这篇文章的JavaScript代码都给过滤掉了。

有趣的Unicode的BOM

《有趣的Unicode的BOM》,这个文章标题抄自周曙光的网络日志这篇同名文章。抄标题的原因,详见文章末尾。呃,看到这里,你的手动了没?动了就是好奇心很强的人。如果是用鼠标拖动滚动条,电脑白痴;按PageDown键或者End键,电脑菜鸟;按Space键或者滚动鼠标滚轮,电脑高手。因为,“不知道IE工具栏第一个按钮的功能的,是普通用户;知道的,是高端用户。”

今天偶然看到那篇文章。(没有订feed看的习惯,555~~)Unicode这玩意很简单,又很复杂,值得好好研究。BOM这东西,有人说它是好东西,有人说它是罪魁祸首,反正说什么的都有。

文章提到3个问题,前两个是我所熟知的,最后一个我是第一次听说,而且在Google搜索一下,只有两个网站提到,自然,一个是我看的这篇文章,一个就是该问题的出处咯。

用Windows记事本写txt文件,在文件开头加入".LOG"字样,那么在每次打开文件时,记事本会自动在文件最后加上当前日期。这个是N久以前的,在Windows 98的时代就有的一个特性。我还记得当时Windows 98发布时,报纸上经常提到这个技巧,说是Windows 98的新功能。另外,微软网站的文档《How to Use Notepad to Create a Log File》里也介绍了这一技巧。(当年Windows 98发布时,我是多么的激动啊,现在的Vista已经没感觉了,唉,年轻不再)这个小技巧好像直到现在还是经常被提起,比如在各大电脑杂志上。而且,经常有人说这是复活节彩蛋。拜托,按下Ctrl+R,输入winrar,回车,点帮助,关于,点一下上面的图片和左边的图标,那个叫复活节彩蛋。隐藏在你身边,在某个值得纪念的日子,比如复活节,被开发商公布看到的办法,或者是你偶然发现,得到的一个惊喜,那个才叫复活节彩蛋。

联通的问题。“联通”二字的编码是"C1AACDA8",当记事本读取的时候会出现判断错误,认为这是一个UTF-8编码文件,以UTF-8编码方式打开,所以出现错误。虽然显示出来的是一个黑块,不过可并不是只有一个字符哦。C1AA的二进制是1100000110101010,按照UTF-8两字节来拆开,Unicode编码是1101010,也就是6A,而两字节的UTF-8要在80以上才能使用,所以这个UTF-8编码是不存在的,所以记事本不显示。而CDA8,二进制1100110110101000,拆开的Unicode编码是1101101000,也就是368。在宋体字符里查了一下,查不到,不知道是那个国家的编码,反正是显示不出来就是了,只能显示一个黑块。所以,文章最后给出的答案,“第一种情况是将联通的Unicode编码54801A90当成ASCII编码解析,所以出现一些方块乱码”,乱讲。还有xfocus论坛2004年1月的这个帖子,说4个字节中,前3个字节被当作BOM,只有第四个字节显示出来,乱讲 too. 不过,能知道UTF-8的BOM是3个字节,已经很高手了。

第三个问题,在记事本中输入"this sentences are notreadable",保存后再打开时变成中文乱码。这个事也是编码判断错误。其实想看记事本把它错误判断成什么编码是很简单的,在打开文件后,点文件->另存为,下面的编码一项就是记事本所认为的文本的编码方式。另外,在文件->打开里,选中一个文本文件,记事本也会立即进行识别,并把认为的编码方式显示在对话框下面的编码项中。(起码在我的Windows XP SP2里是这样的)这个字符写入文件后会被记事本认为是所谓的"Unicode"编码,也就是UTF-16编码。这也是记事本对编码判断的错误。xfocus论坛的那个帖子,说是什么Unicode头,乱讲 too.

联通的问题和第三个问题,都是记事本编码判断错误的问题。这显然不是复活节菜单,也算不上bug。你不告诉软件所打开的文件的编码方式,他当然只能猜咯。猜总是会猜错的嘛。比如行尾符的问题,假如你的文件里就没有换行符,软件又怎么能给你判断呢?不止记事本,就是UEStudio,在打开有“联通”那两个字的文件时,也是认为是UTF-8编码,而且它还把C1AA这个编码给解析出来了,6A对应的字符的小写字母"j",它给显示出来了。不过,经常在网上或者电脑杂志看到这个火星贴被翻出来,还大都加上什么“已经打了最新的SP2”补丁之类的。唉,就知道SP2,SP2出来很久了,那么多Hotfix打了没啊?

最后,该点题了。“有趣的Unicode的BOM”,其实是最可怜的BOM。上述三个问题,和BOM一点关系都没有,可是后两个所谓的“Windows的bug”却被硬赖在BOM身上。我们的BOM,我们的Byte Order Mark,是多么的可怜啊。其实记事本在UTF-8和UTF-16编码的文件开头写入BOM并没有错,因为下次再用记事本打开的时候它就好识别了呀。那么多电脑菜鸟,有谁会在发现乱码之后,在打开对话框里调一下,选择一个正确的编码啊?只会脱口而出:“Windows的bug,Windows真难用。”

P.S. 后两个问题可以作为测试题。当别人回答你“不知道”的时候,电脑白痴;回来“是编码的问题”,电脑菜鸟;提到"Unicode",电脑高手;要是提到BOM,这个人你一定要抓住啊,他就是所谓的牛人啊。在这个知道IE工具栏第一个按钮的功能就是高手的年代,能吐出"BOM"三个字,那是多么牛的人啊,虽然,虽然BOM和这两个问题一点关系都没有。

PS2 找到新浪的一篇报道《微软记事本“闹鬼” 常用汉字输入变黑点》,2003年的,或许联通的问题就是2003年才出现的吧。还有这篇《关于“微软/联通”记事本问题的解释》,介绍的也很详细。“当文档中所有字符都在C0≤AA≤DF,80≤BB≤BF这个范围的时候,notepad都无法确认文档的格式,没有自动按照UTF-8格式来"Display"。”这话好像说反了,如果所有字符都在(C0-DF, 80-BF)这个范围内,文件就会被以UTF-8编码解析。至于原因嘛,嘿嘿,这个范围正好是UTF-8两字节编码的范围:110xxxxx 10xxxxxx (c0-df)(80-bf)。而我觉得,事实上Windows记事本所采用的判断编码的策略,其实就是以UTF-8编码方式解码,如果解码过程没有出现错误,也就是说这个文件按UTF-8编码方式解码没有问题,没有不符合UTF-8编码的字节,那么,记事本就认为他就是一个UTF-8文件。这也是没办法,对于没有BOM的文件来说,只有这个办法。而且,在PHP里判断编码方式也是用的这种办法,我写的程序也是用的这种办法,想要更好的办法?更好的办法就涉及到解析字符串,分析出里面句子的意思,判断是否是符合逻辑的句子了。

html里title属性换行的方法

今天在写插件时,需要在一段字符的title属性里加入一大段文字。字符串本身用UNIX行尾符LF换行。我直接输出字符串,发现在IE和Firefox下都可以显示出断行。

<div title="123
456">text</div>

不过,Firefox的Html Validator扩展报了错。在网上搜了一圈,这里提到:

The (X)HTML DTDs define the contents of the title attribute as CDATA for which the W3C states:
User agents should interpret attribute values as follows:

  • Replace character entities with characters,
  • Ignore line feeds,
  • Replace each carriage return or tab with a single space.

大概的意思是,XHTML DTD定义title属性为一个CDATA,而根据SGML里CDATA的定义,浏览器应该:替换所有html实体;忽略LF字符;替换所有CR字符和tab字符为一个空格。

按照W3C的说法,执行这3步后,所有的CR和LF字符已经他们的html实体都已消失或变成空格了。看起来在title里换行变成不可能的事了。不过,Firefox好像并没有转换CR字符为空格,而是把CR给忽略了。而LF字符倒是没有被处理,直接换行了。上面的代码,不用UNIX行尾符LF,而是用Mac行尾符CR,在IE下还能换行,但是在Firefox下,CR字符直接被忽略了。我还是很想通过W3C的验证,所以做了一下测试,使用LF字符或者LF的html实体& #10;都是可以的。网上流传说可以用CR的html实体& #13;,其实只是IE中可以,Firefox下一样不行。如果不追求符合W3C,那还不如直接把字符串转成UNIX行尾符输出呢。

<div title="123& #10;456">text</div>

还有,title里有小于号和单引号好像并不要紧,但是有双引号就不行了。这么说来,把字符串里的换行和双引号给替换一下输出就行了?唉,复杂复杂,晕了。这里有一个介绍这方面问题的页面,不过没太看懂。

发现CR的全称是Carriage Return,Carriage是字车的意思,Carriage Return意思是字车复位。LF的全称是Line Feed,喂进一行,就是新起一行的意思。这起源于打字机时代,每打到一行的末尾,打字员要手工把字车推回第一列,字车复位后,纸会上升一行。所以就有了ASCII码值为13的CR和ASCII码值为10的LF两个字符。而DOS和Windows下文本文件的新行用CR和LF两个字符表示,UNIX下用LF,Mac下用CR。呼,这些资料大概在上个世纪我就知道了,不过一直记不住两个字符的ASCII码是多少,现在复习一遍,这下我应该能记住了。[via]

P.S. 好像C++里"\n"在Windows下输出CRLF,在UNIX下输出LF,而"\r"输出CR。PHP里是"\n"输出的是LF,"\r"输出的是CR。[via]

Delay in C++

今天想找一个可以在C++里让程序暂停一段时间的方法。找到这篇《Time Delay in C++》,文中提到,Windows下可以用Sleep()函数或者QueryPerformanceCounter()函数。这两个函数都是Windows API。

Sleep()函数还算好用,我在Dev-C++里试了一下,使用Sleep(1000);这样的代码就可以让程序暂停1秒钟。当然,要在程序开头加上#include <windows.h>#include <winbase.h>

还看到有文章说,UNIX下要用小写的sleep()

WordPress 2.0.6 发布

昨晚还在想,WordPress 2.0.6应该快发布了,要准备一下,没想到今天早上一上网,看WordPress的changeset时发现/wp-includes/version.php文件已经被修改了,WordPress 2.0.6已于昨晚9点24分正式发布了。哈,从RC2到release还真是快啊。

这个版本更新不大,具体更新有下列几项:

  1. 在wp_redirect()函数后使用exit命令以结束脚本的运行。[4470]
    只不过有的地方用exit;,有的地方用exit();,呵呵。
  2. 使用$wp=& new WP();这样的代码,添加了&符号。[4487]
    开始觉得这样是为了提高执行速度,后来看了#3267,里面提到$wp = new WP();会"get destroyed before the shutdown hook is called"(在shutdown hook被调用之前销毁),而$wp =& new WP();,"This extends the life of these objects to _after_ the shutdown hook is called."(这将使这些对象的生命期延续到shutdown hook被调用之后。)
    复杂复杂,牵涉到PHP自动销毁对象的问题。
  3. 修正WordPress 2.0.5遗留的,当PHP运行在FastCGI模式时,WP使用wp_redirect()函数进行302转向时出现500错误的bug。[via] [4514]
  4. 解决当MySQL运行在strict mode时在上传文件时出现"WordPress database error: [Field 'post_content_filtered' doesn't have a default value]"错误的问题。[4530]
    现在不用再做那个数据库hack了。
  5. sidebar的按月存档(Archives)列表中的日期格式现在被i18n化了。(所有调用wp_get_archives()函数实现显示按月存档的,无论模版还是Widgets还是SBM,都将被影响)以前要把按月存档(Archives)列表改为中文日期格式需要修改WordPress源代码,点点游做的WordPress中文版就是这么做的。现在WordPress语言包已经可以控制日期格式了。
    这个事情还真是麻烦,最早是2005年7月28日有人报了bug #1540,要求把按月存档的日期格式i18n化。后来我又报了一个#3307。再后来,Ryan终于在[4545]里做了修改。不过,Ryan犯了两个错误,写错了__()函数的名称和错改了两个不该被i18n化的字符串。然后,nbachiyski报了bug #3438,要求把那两个错改的字符串改回来,结果被Mark无情地驳回。我又在#3438里对这个问题做了更详细的说明,最终Mark表示认同。Ryan在[4636][4641]里把两个错误都改正了。唉,一点点小事,费了这么大周折。
  6. gettext中,array_shift()函数的参数要求是一个变量,而非函数的返回值。[via] [4555]
  7. 修正了处理MD5字符串的正则表达式的错误。[4581]
    这儿可能引起攻击,不过我没想出攻击的办法。
  8. 在删除文章时,修改属于该文章的附件的post_parent值。[4602]
  9. 一个新过滤器"query",允许插件截获SQL语句,并进行处理。需要注意的是,有些SQL语句是在插件被载入之前被发送的,如果要对这部分SQL语句进行处理,则需要插件放一个特殊的文件做hack,并且需要使用WP 2.1才行。[4620]
  10. Quicktags(就是不使用可视化编辑器时编辑框上面的一排小按钮)现在可以在Safari浏览器中使用了。[4640]
  11. 新的anti-XSS function(防XSS跨站脚本攻击的函数)——attribute_escape()。[4656]
    其实里面就一行代码:return wp_specialchars($text, true);
  12. 添加了"js_escape"和"attribute_escape"两个过滤器。[4661]
  13. 修正了某些恶意评论破坏Blog页面的问题。#2714 [4662]
  14. 在clean_url()函数里对协议名称进行检查。[4672]
    报的bug在#3515,里面给出的代码我尝试了一下,就是下面的第一个评论。点一下评论作者名称,就会弹出一个对话框显示cookie。
  15. 接收Trackback并进行处理时的一些调整。[4677]
    这个修改有点麻烦,stripslashes()函数是不可以乱用的。[via]
  16. Blogger导入工具现在写明只能导入旧的blogger.com帐号,不能支持Google新推出的Blogger。这是因为Google在2006年12月底已经把以前的Blogger beta正式发布了。[4680]
  17. Akismet做了点小修改,把整理wp_comments表的概率从4/5降低到1/1000。

参考:在WordPress 2.0.6里被解决的bug列表WordPress 2.0.6 Content Summar。从后一个地址得到一个消息:

The WordPress 2.0 series is now officially on its way to becoming part of the Debian Stable product and as a result, and as discussed in October, patches will continue to be released in 2.0 series for the next 3-5 years.

看来,WordPress 2.0系列要一直更新下去了。嘿嘿,等到WordPress 2.0.10的时候,我就是元老啦。

WordPress 2.0.6的升级方法嘛,上传文件,覆盖,完了。有需要修改的文件,比如/wp-includes/wp-db.php文件,记得修改下。

另外,WordPress 中文包已更新,没啥变化,除了Blogger导入工具有所修改,以及“按月存档”列表日期格式的i18n化。我把月份的翻译全部改成了类似“1月”这样,然后把"%1$s %2$d"翻译成"%2$d年%1$05s",这样,sidebar里的“按月存档”就会显示成“2006年01月”、“2006年11月”这样了。要求Blog编码方式使用UTF-8时才行,因为UTF-8里汉字占3个字节,再加上两位数字,正好5位。我翻了半天PHP手册才弄出来的,很不错吧 :)

WordPress在中文世界有不少人在使用,虽然国内的IIS+ASP主机的价格比Apache+PHP要便宜很多。每次WordPress升级,都会例行性地出现一些现象:很多Blog上会写一篇文章,《WordPress 2.0.6发布啦》,然后配上从WordPress开发日志里拷过来的几条更新日志,有的直接贴英文原文,好心一点的还给翻译下。然后再贴一段广为流传的极其复杂的升级步骤,大致是“备份某些文件,停用插件,再删除全部文件,上传新文件,恢复某些文件,再一个一个启用插件。”同时,还会有一帮人大呼小叫。比如,“没必要升级新版,够用就好。”、“2.0.5和2.0.6相比哪个速度更快些?”、“中文版发布了吗?”。够用就好是不错,不过,这种小升级一般都是bug fix,你连changelog都不看就可以断定这些bug不会影响到你吗?速度更快么,这种小升级哪能比较出速度来?又不是WP 1.5和WP 2.0相比。中文版,唉,很多人需要的是中文版,中文包用不了,建一个目录上传一个文件太累了。而且,2.0.6的中文包比起上一版来只增加了几项,新中文包没出来之前,先升级了WordPress本身又能怎样?

另外,我一直认为WordPress开发组发布新版本是为了修复bug的,可是某些人却一直确信,WordPress开发组发布新版本是为了制造bug,让WordPress运行速度更慢,或者是无聊想逼着用户升级的。

P.S. WordPress 2.0.7已经在筹备中,WordPress 2.1已经beta 1了,期待ing。既然2.1已经beta了,大概WordPress开发组会把工作中心转到2.1上吧,2.1应该会在2.0.7之前发布。

Update:偶然间看到/wp-includes/wp-db.php文件的最后$wpdb = new wpdb(DB_USER, DB_PASSWORD, DB_NAME, DB_HOST);这一句还没有加上&符号,不知道会不会引起问题。WordPress开发组好像已经开始着手解决WordPress运行在PHP 5.2和FastCGI下的问题,Mark已经弄了个PHP 5.2的测试环境。svn里已经有了做了一些修改,这个问题有望在WordPress 2.0.7里和WordPress 2.1里解决。

WordPress 2.0.5里有几个攻击办法,正在研究中。