分类于 代码人生 | 998 次点击 | 评论(3) »
由 Apex 发表于

使用Visual Studio 2008写代码时,编译时遇到警告:

  1. 1>d:\program\msvs2008\vc\include\cstdio(49) : warning C4995: 'gets': name was marked as #pragma deprecated
  2. 1>d:\program\msvs2008\vc\include\cstdio(53) : warning C4995: 'sprintf': name was marked as #pragma deprecated
  3. 1>d:\program\msvs2008\vc\include\cstdio(56) : warning C4995: 'vsprintf': name was marked as #pragma deprecated
  4. 1>d:\program\msvs2008\vc\include\cstring(22) : warning C4995: 'strcat': name was marked as #pragma deprecated
  5. 1>d:\program\msvs2008\vc\include\cstring(23) : warning C4995: 'strcpy': name was marked as #pragma deprecated
  6. 1>d:\program\msvs2008\vc\include\cwchar(36) : warning C4995: 'swprintf': name was marked as #pragma deprecated
  7. 1>d:\program\msvs2008\vc\include\cwchar(37) : warning C4995: 'vswprintf': name was marked as #pragma deprecated
  8. 1>d:\program\msvs2008\vc\include\cwchar(39) : warning C4995: 'wcscat': name was marked as #pragma deprecated
  9. 1>d:\program\msvs2008\vc\include\cwchar(41) : warning C4995: 'wcscpy': name was marked as #pragma deprecated

意思是说,某个函数已经被标记为过时了,最好不要用,在将来的版本中,该函数可能就没有了,不存在了。

奇怪的是,代码里面并没有使用这些函数啊。但是先不考虑这个了,还是看看如何解决吧。对于编译器警告,当然可以用 #pragma warning(disable: xxxx ) 的语法将其禁止掉,这样编译时编译器就不会在那里唧唧歪歪了。在网上查找此类问题,基本上都是这样说的。

然后仔细想想,关闭这个警告并不正常,因为这样一来,所有过时的函数都不会再警告了,而我们可能是需要这个警告的,像是对于strcpy这种超常用的函数,考虑到安全性(应对缓冲区溢出攻击),我们的确应该使用其安全版本,例如strcpy就有对应的StringCchCopy/StringCbCopy这样的函数,如果关闭了此警告,我们就可能在代码中不小心写下strcpy,而不是其对应的安全版本(当然,strcpy等函数是特例,关闭C4995警告后,仍然会有其他警告,下面有说明)。

所以,考察上述几个函数,我们知道其函数声明所在的头文件,这些头文件中的函数应该都不会用到,所以可以用另一种方式来避免引入这些头文件:

在你的工程的预编译头文件(一般来说,就是stdafx.h)中,在 #pragma once 一行后面加上下列三行:

  1. #define _CSTDIO_
  2. #define _CSTRING_
  3. #define _CWCHAR_

这样,编译器就不会再加载 cstdio / cstring / cwchar 这几个头文件了。

P.S.
使用 #pragma warning(disable: xxxx) 这种方式关闭警告后,如果代码里面用到了 strcpy 这样的函数,编译器会报另一个警告:

  1. 1>e:\work\ncksoft\test\main.cpp(126) : warning C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
  2. 1>        d:\program\msvs2008\vc\include\string.h(74) : see declaration of 'strcpy'

所以我们仍然可以得到想要的警告信息。

再 P.S.
如果在代码中使用 #pragma deprecated( name_of_deprecated ) ,就会在编译时报 C4995 警告,而使用下面的方法,则会报 C4996 警告:

  1. __declspec(deprecated) void foo(int) {
  2.    // ...
  3. }

再 再 P.S.
我很讨厌那些将警告信息视作无物的程序员,一点美感都没有!

分类于 代码人生 | 547 次点击 | 评论(3) »
由 Apex 发表于

最近在研究网站提速、搜索引擎优化等技术,打算将一些技巧逐步分享,这里先说说提速。

对于基于PHP构建的网站,一个可行的方法是将网络上传输的内容减少。一是压缩,二是如果内容没有发生变化,则不发送内容到客户端,而是让客户端使用缓存的数据。虽然说现在网络速度已经比较快了,但是考虑到网页大部分都是文本内容,压缩率还是相当可观的,一般来说,构成网页的文本内容如HTML/CSS/JS等,使用gzip压缩可以达到60%以上的压缩率。这样,一个简单的网站页面每次访问也可减少60KB以上的网络传输量。而压缩操作速度是很快的,一个100KB的页面文本,压缩耗时在3毫秒以下,基本可以忽略。

我打算先从css/javascript文件入手。下面来看一段代码:
阅读这篇日志的剩余部分 »

分类于 PKI | 609 次点击 | 评论(6) »
由 Apex 发表于

好久没有写日志了,倒不是这段时间没有所思,而是思得太多,做的也更多,也就没有时间写了。好了,言归正传,下面我们接着说说《谈谈网银和USB Key (四)》中最后提到的“带确定按键的USB Key仍然不够安全”的原因。

是的,带确定按键的USB Key可以做到每次使用硬件内部的私有密钥时都是持有者明确授权的(即持有者做了按下确认键的操作),但是不要忘记,你能保证被签名的数据就一定是你想要签名的数据吗?这句话听起来有点绕口,那么我们来举一个例子:

特别注明:本文中所提到的商家、银行、地点、人物等均为举例方便而用,没有任何明确或隐含的意义。如有雷同,那一定是你踩到狗屎了~~~
阅读这篇日志的剩余部分 »

分类于 WordPress相关 | 365 次点击 | 评论(1) »
由 Apex 发表于

很久都没有更新博客了,实在是最近太忙了。这不,前两天趁着WordPress最新版本2.8正式发布,我终于抽了个时间做了一次系统升级。

没有想到的是,忙中出错,升级后系统后台管理进不去了,即使密码是正确的,登录后也只是显示一个“你没有对应的权限!”就把我打发了。没办法,只好临时备份了一下原来的数据库,然后重新创建了一个新的数据库,总算是可以登陆了。

我是从2.5直接升级到2.7的,后台变化太大了,但是感觉非常的棒。

左思右想,让我一直很喜欢的WordPress不应该出现这么低级的错误啊,升级后不应该不能用了。于是仔细检查升级过程所做的操作,果然发现问题:在修改配置文件的时候,原来的数据库没有设定所用的字符集,后台老版本缺省使用的是拉丁字符集,新版本缺省使用UTF-8字符集。屏蔽字符集设定,切换回旧的数据库,一切正常了,原来的插件都能用,自己设计的主题DeepWater也显示正常,真好。

嗯嗯,经验值涨17点~~~

过段时间有空了,写个脚本,将原来的数据库内容全部转换为UTF-8,以适应世界潮流,哇哈哈哈~~~~~

分类于 PKI, 代码人生 | 748 次点击 | 评论(3) »
由 Apex 发表于

自从六年前我从ASP阵营弃暗投明转向PHP阵营之后,就不时的与Apache打交道,Apache的配置也从1.3研究到2.2版。但是有一个问题一直困扰我,而且它不定时的就冒出来打击我一下,让我很是郁闷。

这个问题是这样的:把网站设置为需要进行SSL双向认证(即通过https://的方式访问网站,还需要有客户端数字证书),如果服务端是基于Apache的话,那么客户端(也就是浏览器)每次访问一个页面,对于页面上的每一份资源(一个页面通常包含很多资源,例如被html页面引用的.js/.css文件,页面中的各个图片、flash等等),都需要做一次数字签名。奇怪的是IIS服务器就没有这种情况。

每访问一个资源就做一次数字签名,这是一件恐怖的事情。一般情况下一个html页面都会包含十几个甚至几十个资源(特别是一些装饰用的小图片和一些小图标等等,每个文件也就两三KB,但是也需要进行数字签名),早期使用数字证书的时候基本上都是将数字证书保存在计算机硬盘上,数字签名也是由CPU来进行,一次数字签名也就几个毫秒,看起来影响就不大,但是随着技术的发展,后来都是以USB Key来对数字证书进行存储和运算,为了安全,数字签名就只能USB Key内部进行。试想一下,处理器速度一般就几M,高的也就几十M的USB Key处理芯片,在做数字签名的时候效率比起计算机两三个G的运算速度低了不少,即使经过特别优化,一般的USB Key做一次数字签名也需要十多二十毫秒。这种情况下,每访问一个资源就需要做一次数字签名,在打开一个网页的时候,就会发现有明显的延时,现象就是页面文字都已经显示出来了,而USB Key的指示灯还在狂闪(USB Key上通常有一个指示灯,当USB Key正在工作的时候就会闪烁,以提醒用户),然后才能够看到页面上的图片内容一个一个的显示出来。

这几年里,对于这个问题我一直都不求甚解,当初想通过修改Apache配置来解决,也试图在PHP脚本中加入Keep-alive之类的标记,但是终不得其法,渐渐的也就有了一个错误的认识,那就是Apache无法做到SSL状态的缓存,客户端访问每个SSL资源都必须重新重新经历握手、产生会话密钥等过程,所以每访问一个资源就会做一次数字签名。

这个错误的认识一直延续了好几年,在这几年中,当有人问到我这方面的问题时,我都毫不犹豫的告诉他这是Apache的问题,是出于安全性考虑才这样做的。但是另一方面,在我内心深处,还是隐约觉得事情不应该是这样的。终于,在一次封闭开发的过程中,我弄明白了事情的真相。
阅读这篇日志的剩余部分 »

页面导航 (1/18)12345»...最后一页 »