mirror of
https://github.com/ZLMediaKit/ZLMediaKit.git
synced 2026-07-28 21:14:03 +08:00
test: cover AMF array nesting limits
This commit is contained in:
@@ -18,39 +18,95 @@
|
|||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace toolkit;
|
using namespace toolkit;
|
||||||
|
|
||||||
static string make_nested_object(size_t depth) {
|
enum class ContainerType {
|
||||||
|
Object,
|
||||||
|
EcmaArray,
|
||||||
|
StrictArray,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const char *container_name(ContainerType type) {
|
||||||
|
switch (type) {
|
||||||
|
case ContainerType::Object:
|
||||||
|
return "object";
|
||||||
|
case ContainerType::EcmaArray:
|
||||||
|
return "ECMA array";
|
||||||
|
case ContainerType::StrictArray:
|
||||||
|
return "strict array";
|
||||||
|
}
|
||||||
|
return "unknown";
|
||||||
|
}
|
||||||
|
|
||||||
|
static AMFType container_amf_type(ContainerType type) {
|
||||||
|
switch (type) {
|
||||||
|
case ContainerType::Object:
|
||||||
|
return AMF_OBJECT;
|
||||||
|
case ContainerType::EcmaArray:
|
||||||
|
return AMF_ECMA_ARRAY;
|
||||||
|
case ContainerType::StrictArray:
|
||||||
|
return AMF_STRICT_ARRAY;
|
||||||
|
}
|
||||||
|
return AMF_UNDEFINED;
|
||||||
|
}
|
||||||
|
|
||||||
|
static string make_nested_container(ContainerType type, size_t depth) {
|
||||||
string result;
|
string result;
|
||||||
for (size_t i = 0; i < depth; ++i) {
|
for (size_t i = 0; i < depth; ++i) {
|
||||||
result.append("\x03\x00\x01x", 4);
|
switch (type) {
|
||||||
|
case ContainerType::Object:
|
||||||
|
result.append("\x03\x00\x01x", 4);
|
||||||
|
break;
|
||||||
|
case ContainerType::EcmaArray:
|
||||||
|
result.append("\x08\x00\x00\x00\x01\x00\x01x", 8);
|
||||||
|
break;
|
||||||
|
case ContainerType::StrictArray:
|
||||||
|
result.append("\x0A\x00\x00\x00\x01", 5);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
result.append("\x05", 1);
|
result.append("\x05", 1);
|
||||||
for (size_t i = 0; i < depth; ++i) {
|
if (type != ContainerType::StrictArray) {
|
||||||
result.append("\x00\x00\x09", 3);
|
for (size_t i = 0; i < depth; ++i) {
|
||||||
|
result.append("\x00\x00\x09", 3);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool accepts_nesting_limit(ContainerType type) {
|
||||||
|
BufferLikeString input(make_nested_container(type, 64));
|
||||||
|
AMFDecoder decoder(input, 0);
|
||||||
|
try {
|
||||||
|
return decoder.load<AMFValue>().type() == container_amf_type(type);
|
||||||
|
} catch (const runtime_error &) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool rejects_excessive_nesting(ContainerType type) {
|
||||||
|
BufferLikeString input(make_nested_container(type, 65));
|
||||||
|
AMFDecoder decoder(input, 0);
|
||||||
|
try {
|
||||||
|
decoder.load<AMFValue>();
|
||||||
|
} catch (const runtime_error &ex) {
|
||||||
|
return string(ex.what()) == "Maximum AMF nesting depth exceeded";
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
{
|
const ContainerType types[] = {
|
||||||
BufferLikeString input(make_nested_object(64));
|
ContainerType::Object,
|
||||||
AMFDecoder decoder(input, 0);
|
ContainerType::EcmaArray,
|
||||||
if (decoder.load<AMFValue>().type() != AMF_OBJECT) {
|
ContainerType::StrictArray,
|
||||||
cerr << "AMF object at the nesting limit was not decoded" << endl;
|
};
|
||||||
|
|
||||||
|
for (auto type : types) {
|
||||||
|
if (!accepts_nesting_limit(type)) {
|
||||||
|
cerr << "AMF " << container_name(type) << " at the nesting limit was not decoded" << endl;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
if (!rejects_excessive_nesting(type)) {
|
||||||
|
cerr << "AMF " << container_name(type) << " beyond the nesting limit was not rejected" << endl;
|
||||||
{
|
|
||||||
BufferLikeString input(make_nested_object(65));
|
|
||||||
AMFDecoder decoder(input, 0);
|
|
||||||
bool depth_rejected = false;
|
|
||||||
try {
|
|
||||||
decoder.load<AMFValue>();
|
|
||||||
} catch (const runtime_error &ex) {
|
|
||||||
depth_rejected = string(ex.what()) == "Maximum AMF nesting depth exceeded";
|
|
||||||
}
|
|
||||||
if (!depth_rejected) {
|
|
||||||
cerr << "AMF object beyond the nesting limit was not rejected" << endl;
|
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user