PHP4.4.2中关于BASE64编码中的一点BUG

来源:互联网 发布:诲女知之乎知的意思 编辑:程序博客网 时间:2024/05/22 16:44

今天偶然调试时,发现了base64编码时内存分配的BUG,为编码分配的缓冲区计算方式有隐患,偶尔出现缓冲区过小,导致后续堆内存被覆盖,访问越界.

php-4.4.2/ext/standard/base64.c

/* {{{ php_base64_encode */
PHPAPI unsigned char *php_base64_encode(const unsigned char *str, int length, int *ret_length)
{
 const unsigned char *current = str;
 unsigned char *p;
 unsigned char *result;

 if ((length + 2) < 0 || ((length + 2) / 3) >= (1 << (sizeof(int) * 8 - 2))) {
  if (ret_length != NULL) {
   *ret_length = 0;
  }
  return NULL;
 }

 result = (unsigned char *)safe_emalloc(((length + 2) / 3) * 4, sizeof(char), 1);
 p = result;

 while (length > 2) { /* keep going until we have less than 24 bits */
  *p++ = base64_table[current[0] >> 2];
  *p++ = base64_table[((current[0] & 0x03) << 4) + (current[1] >> 4)];
  *p++ = base64_table[((current[1] & 0x0f) << 2) + (current[2] >> 6)];
  *p++ = base64_table[current[2] & 0x3f];

  current += 3;
  length -= 3; /* we just handle 3 octets of data */
 }

 /* now deal with the tail end of things */
 if (length != 0) {
  *p++ = base64_table[current[0] >> 2];
  if (length > 1) {
   *p++ = base64_table[((current[0] & 0x03) << 4) + (current[1] >> 4)];
   *p++ = base64_table[(current[1] & 0x0f) << 2];
   *p++ = base64_pad;
  } else {
   *p++ = base64_table[(current[0] & 0x03) << 4];
   *p++ = base64_pad;
   *p++ = base64_pad;
  }
 }
 if (ret_length != NULL) {
  *ret_length = (int)(p - result);
 }
 *p = '/0';
 return result;

我觉得计算方式应改为如下:

 /* Account the result buffer size and alloc the memory for it. */
 if ((length % 3) != 0)
 {
  padnum = 3 - length % 3;
 }

 retsize = (length + padnum) + ((length + padnum) / 3) + 1; // 正确的大小
稍微解释一下,因为BASE64需要将3个8位字节转换成4个6位的元组,4个6位元组每一组都可以用编码表中的一个ASCII码表示,这样的话,即就是每3个字节会多出一个字节,所以最终编码应该多出((length + padnum) / 3)个. 原理就是如此,而standard中默认的编码内存分配计算得有隐患.

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 液氮挥发太快怎么办 高铁上空调太冷怎么办 文登市昆嵛酒店怎么办 厦漳泉同城包怎么办 亲戚朋友总是蹭吃蹭喝怎么办啊 开车上班总有蹭车的怎么办 食堂的饭难吃怎么办 租亲戚的房子怎么办 饭菜罩子生虫怎么办 食堂吃出虫子怎么办 缺氧没有煤炭了怎么办 缺氧没有金属了怎么办 白色衣服带红色怎么办 如果买方退回假货怎么办 饰品氧化变黑了怎么办 银放久了变黄怎么办 真银变色了怎么办 古装头饰变色了怎么办 液晶电视遥控器坏了怎么办 纯银手镯发黑怎么办 银色项链黑了怎么办 线切割割铜割不动怎么办 楼房一直不动工怎么办 买火车票待审核怎么办 太原动车月票怎么办 发票上没有日期怎么办 火车没有坐票怎么办 如果买到无座的火车票怎么办 动车票来不及去怎么办 火车票被洗了怎么办 进站后走错站台怎么办 高铁票迟到了怎么办 12306生日错了怎么办 账号未通过核验怎么办 高铁票购票失败怎么办 天际线没有人口需求怎么办 复兴号 锁 区间 怎么办 地板砖上铺木地板门怎么办 高考座位号没涂该怎么办 一个人带小孩很累很烦怎么办 收割机麦立怎么办漏