ホームページ > バックエンド開発 > PHPチュートリアル > Phpバイナリセキュリティの詳しい解説

Phpバイナリセキュリティの詳しい解説

小云云
リリース: 2023-03-22 17:02:02
オリジナル
2076 人が閲覧しました

本文主要和大家分享Php二进制安全详解,希望能帮助到大家。

1. php的二进制安全 binary-safe

php的内部函数在操作二进制数据时能保证达到预期的结果,例如 str_replacestristrstrcmp 等函数,我们就说这些函数是二进制安全的。

下面通过 c 语言 和  php 的对比 来看 他们对二进制数据的处理
#include "stdio.h"#include "string.h"int main(){char a[] = "aa\0b";char b[] = "aa\0c";printf("%d\n", strcmp(a, b));printf("%ld\n", strlen(a));
}/* 0 2 */
ログイン後にコピー
ログイン後にコピー
可以看出来 c语言 "\0" 是字符串结束,所以认为 "aa\0b'"aa\0c" 是一样的,长度为2 抛弃了 "\0b""\0c" .
<?php/**
 * Created by PhpStorm.
 * User: leon
 * Date: 17/11/6
 * Time: 上午10:24
 */
    $a = "aa\0b";    $b = "aa\0c";    $c = "\0\0";    $d = &#39;a&#39;;    $e = &#39;a&#39;;
    var_dump(strcmp($a, $b));
    var_dump(strcmp($c, $d));
    var_dump(strlen($a));
    var_dump(strlen($c));

# res : int(-1) int(0) int(4) int(2)
ログイン後にコピー
ログイン後にコピー
php "aa\0b""aa\0c" 是不同的 ,并且长度为4

2. php实现二进制安全的原理

PHP中字符串通过 zend_string 表示:
Phpバイナリセキュリティの詳しい解説

PHP中 变量 zend_value 表示:
Phpバイナリセキュリティの詳しい解説

  • gc: 变量引用信息,比如当前value的引用数,所有用到引用计数的变量类型都会有这个结构,3.1节会详细分析

  • h: 哈希值,数组中计算索引时会用到

  • len: 字符串长度,通过这个值保证二进制安全

  • val: 字符串内容,变长struct,分配时按len长度申请内存


  • len: 字符串长度,通过这个值保证二进制安全 ,它不需要像C 一样用哟 ‘\0’ 结尾符来判断字符串的结束,而是通过len

3.SDS

C : 以 ’\0’ 为结束符,所以c的字符串不能包含文本,图片、音频、视频、压缩文件这样的二进制数据。
Php : 记录 len
SDS : simple dynamic string 简单动态字符串的抽象类型,应用到字符表示:

SDS 数据结构:

struct sdshdr {    # 记录 buf 数组中已使用字节的数量
    # 等于 SDS 所保存字符串的长度
    int len;    # 记录 buf 数组中未使用字节的数量
    int free;    # 字节数组,用于保存字符串
    char buf[];
};
ログイン後にコピー
ログイン後にコピー

redis 的结构定义中也记录了SDS所保存字符串的长度,通过这个值保证二进制安全,SDS 的 API 都会用 字符串的len 属性来判断字符串是否结束

1. php的二进制安全 binary-safe

php的内部函数在操作二进制数据时能保证达到预期的结果,例如 str_replacestristrstrcmp 等函数,我们就说这些函数是二进制安全的。

下面通过 c 语言 和 php 的对比 来看 他们对二进制数据的处理
#include "stdio.h"#include "string.h"int main(){char a[] = "aa\0b";char b[] = "aa\0c";printf("%d\n", strcmp(a, b));printf("%ld\n", strlen(a));
}/* 0 2 */
ログイン後にコピー
ログイン後にコピー
可以看出来 c语言 "\0" 是字符串结束,所以认为 "aa\0b&#39;"aa\0c" 是一样的,长度为2 抛弃了 "\0b""\0c" .
<?php/**
 * Created by PhpStorm.
 * User: leon
 * Date: 17/11/6
 * Time: 上午10:24
 */
    $a = "aa\0b";    $b = "aa\0c";    $c = "\0\0";    $d = &#39;a&#39;;    $e = &#39;a&#39;;
    var_dump(strcmp($a, $b));
    var_dump(strcmp($c, $d));
    var_dump(strlen($a));
    var_dump(strlen($c));

# res : int(-1) int(0) int(4) int(2)
ログイン後にコピー
ログイン後にコピー
php "aa\0b""aa\0c" 是不同的 ,并且长度为4

2. php实现二进制安全的原理

PHP中字符串通过 zend_string 表示:
Phpバイナリセキュリティの詳しい解説

PHP中 变量 zend_value 表示:
Phpバイナリセキュリティの詳しい解説

  • gc: 变量引用信息,比如当前value的引用数,所有用到引用计数的变量类型都会有这个结构,3.1节会详细分析

  • h: 哈希值,数组中计算索引时会用到

  • len: 字符串长度,通过这个值保证二进制安全

  • val: 字符串内容,变长struct,分配时按len长度申请内存


  • len: 字符串长度,通过这个值保证二进制安全 ,它不需要像C 一样用哟 ‘\0’ 结尾符来判断字符串的结束,而是通过len

3.SDS

C : 以 ’\0’ 为结束符,所以c的字符串不能包含文本,图片、音频、视频、压缩文件这样的二进制数据。
Php : 记录 len
SDS : simple dynamic string 简单动态字符串的抽象类型,应用到字符表示:

SDS 数据结构:

struct sdshdr {    # 记录 buf 数组中已使用字节的数量
    # 等于 SDS 所保存字符串的长度
    int len;    # 记录 buf 数组中未使用字节的数量
    int free;    # 字节数组,用于保存字符串
    char buf[];
};
ログイン後にコピー
ログイン後にコピー

redis 的结构定义中也记录了SDS所保存字符串的长度,通过这个值保证二进制安全,SDS 的 API 都会用 字符串的len 属性来判断字符串是否结束。

相关推荐:

php二进制安全的含义

phpバイナリセキュリティ_PHPチュートリアル

PHP関数のバイナリセキュリティに関連する問題

以上がPhpバイナリセキュリティの詳しい解説の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート