目录
1:将析构设置成私有
// 一旦析构函数设置成protected,private,那么该类只能
// 通过new 和 delete 实例,删除,
// A a; 会报错
#include "iostream"
class A
{
public:
A(){ std::cout << "A" << std::endl; }
private:
~A(){ std::cout << "~A" << std::endl; }
};
int main()
{
//A a;
A *a=new A();
}
2:防止sql注入
用户输入 player 和密码。验证登入时,直接将数据拼装查询数据库
a:绕过身份验证的sql注入, 使用OR
正常情况下: select * from t_player WHERE player=1 and Pwd="ju83hjas923r9";
sql注入: select * from t_player WHERE player=1 and Pwd=1 or 1=1;
b:使用#过滤后面的条件
正常情况下: select * from t_player WHERE player=1 and pwd="fajjdfladf";
sql注入(#):select * from t_player WHERE player=1# and pwd="fajjdfladf";
c:还有很多其他的,不过暂时看不懂,按照上面的逻辑,触发删除/修改 的,会很严重的
防御方法:
a:编写过滤函数,将客户端提交的数据,过滤掉 select ,update 等sql 常用的关键词
b:加密处理
用户密码输入 1 or player=1 ,如果直接去查询,那么就会绕过密码验证
如果数据库保存的密码是经过加密的,
我们查询的时候,就需要将用户输入的,进行加密,再去 sql查询
如MD5加密变成 0f8fad117740dc78cb2e834068b94fab
那么用户输入什么多没办法绕过验证
3:WIndow下类或函数给其他dll,ext使用
在window下当我们在自己所在的dll写了一个类,其他库,需要初始化,或调用他的时候我们需要
在写这个类的时候 加上 __declspec(dllexport)
class __declspec(dllexport) CTest
{
}
或者写的是函数
__declspec(dllexport) int getNum();
4:sprintf 格式化,整形注意
%d 有符号32位整数
%u 无符号32位整数
%lld 有符号64位整数
%llu 无符号64位
%llx有符号64位16进制整数
注意点:当你设置%llu 的时候传入 无符号32位,会乱码
5:函数不确定参数(纯c实现的),实现printf
#include <stdarg.h>
#include <stdio.h>
void myPrint(const char *format, ...)
{
char buf[1024];
char *pp = buf;
va_list args;
va_start(args, format);
vsprintf_s(pp ,1024,format, args);
va_end(args);
printf("%s", pp);
}