From c65a6b5d631009c94fc0bbdfb11e2185b4feb635 Mon Sep 17 00:00:00 2001 From: winlin Date: Sun, 20 Jul 2014 16:16:29 +0800 Subject: [PATCH] fix the conf_line bug of parse config directive. --- trunk/src/app/srs_app_config.cpp | 28 ++++--- trunk/src/app/srs_app_config.hpp | 3 +- trunk/src/utest/srs_utest_config.cpp | 114 +++++++++++++++++++++++++++ 3 files changed, 132 insertions(+), 13 deletions(-) diff --git a/trunk/src/app/srs_app_config.cpp b/trunk/src/app/srs_app_config.cpp index 92e6ef221..4be4e56dc 100644 --- a/trunk/src/app/srs_app_config.cpp +++ b/trunk/src/app/srs_app_config.cpp @@ -154,8 +154,8 @@ int SrsConfDirective::parse_conf(_srs_internal::SrsConfigBuffer* buffer, SrsDire while (true) { std::vector args; - - ret = read_token(buffer, args); + int line_start = 0; + ret = read_token(buffer, args, line_start); /** * ret maybe: @@ -170,14 +170,14 @@ int SrsConfDirective::parse_conf(_srs_internal::SrsConfigBuffer* buffer, SrsDire } if (ret == ERROR_SYSTEM_CONFIG_BLOCK_END) { if (type != parse_block) { - srs_error("line %d: unexpected \"}\", ret=%d", buffer->line + 1, ret); + srs_error("line %d: unexpected \"}\", ret=%d", buffer->line, ret); return ret; } return ERROR_SUCCESS; } if (ret == ERROR_SYSTEM_CONFIG_EOF) { if (type == parse_block) { - srs_error("line %d: unexpected end of file, expecting \"}\", ret=%d", conf_line + 1, ret); + srs_error("line %d: unexpected end of file, expecting \"}\", ret=%d", conf_line, ret); return ret; } return ERROR_SUCCESS; @@ -185,14 +185,14 @@ int SrsConfDirective::parse_conf(_srs_internal::SrsConfigBuffer* buffer, SrsDire if (args.empty()) { ret = ERROR_SYSTEM_CONFIG_INVALID; - srs_error("line %d: empty directive. ret=%d", conf_line + 1, ret); + srs_error("line %d: empty directive. ret=%d", conf_line, ret); return ret; } // build directive tree. SrsConfDirective* directive = new SrsConfDirective(); - directive->conf_line = buffer->line; + directive->conf_line = line_start; directive->name = args[0]; args.erase(args.begin()); directive->args.swap(args); @@ -210,7 +210,7 @@ int SrsConfDirective::parse_conf(_srs_internal::SrsConfigBuffer* buffer, SrsDire } // see: ngx_conf_read_token -int SrsConfDirective::read_token(_srs_internal::SrsConfigBuffer* buffer, vector& args) +int SrsConfDirective::read_token(_srs_internal::SrsConfigBuffer* buffer, vector& args, int& line_start) { int ret = ERROR_SUCCESS; @@ -260,7 +260,7 @@ int SrsConfDirective::read_token(_srs_internal::SrsConfigBuffer* buffer, vector< if (ch == '{') { return ERROR_SYSTEM_CONFIG_BLOCK_START; } - srs_error("line %d: unexpected '%c'", buffer->line + 1, ch); + srs_error("line %d: unexpected '%c'", buffer->line, ch); return ERROR_SYSTEM_CONFIG_INVALID; } @@ -273,19 +273,19 @@ int SrsConfDirective::read_token(_srs_internal::SrsConfigBuffer* buffer, vector< switch (ch) { case ';': if (args.size() == 0) { - srs_error("line %d: unexpected ';'", buffer->line + 1); + srs_error("line %d: unexpected ';'", buffer->line); return ERROR_SYSTEM_CONFIG_INVALID; } return ERROR_SYSTEM_CONFIG_DIRECTIVE; case '{': if (args.size() == 0) { - srs_error("line %d: unexpected '{'", buffer->line + 1); + srs_error("line %d: unexpected '{'", buffer->line); return ERROR_SYSTEM_CONFIG_INVALID; } return ERROR_SYSTEM_CONFIG_BLOCK_START; case '}': if (args.size() != 0) { - srs_error("line %d: unexpected '}'", buffer->line + 1); + srs_error("line %d: unexpected '}'", buffer->line); return ERROR_SYSTEM_CONFIG_INVALID; } return ERROR_SYSTEM_CONFIG_BLOCK_END; @@ -308,6 +308,10 @@ int SrsConfDirective::read_token(_srs_internal::SrsConfigBuffer* buffer, vector< } } else { // last charecter is not space + if (line_start == 0) { + line_start = buffer->line; + } + bool found = false; if (d_quoted) { if (ch == '"') { @@ -2847,7 +2851,7 @@ namespace _srs_internal { SrsConfigBuffer::SrsConfigBuffer() { - line = 0; + line = 1; pos = last = start = NULL; end = start; diff --git a/trunk/src/app/srs_app_config.hpp b/trunk/src/app/srs_app_config.hpp index 29712cca2..0f85e7de2 100644 --- a/trunk/src/app/srs_app_config.hpp +++ b/trunk/src/app/srs_app_config.hpp @@ -215,9 +215,10 @@ private: * read a token from buffer. * a token, is the directive args and a flag indicates whether has child-directives. * @param args, the output directive args, the first is the directive name, left is the args. + * @param line_start, the actual start line of directive. * @return, an error code indicates error or has child-directives. */ - virtual int read_token(_srs_internal::SrsConfigBuffer* buffer, std::vector& args); + virtual int read_token(_srs_internal::SrsConfigBuffer* buffer, std::vector& args, int& line_start); }; /** diff --git a/trunk/src/utest/srs_utest_config.cpp b/trunk/src/utest/srs_utest_config.cpp index b44932211..b5dd727e1 100644 --- a/trunk/src/utest/srs_utest_config.cpp +++ b/trunk/src/utest/srs_utest_config.cpp @@ -663,3 +663,117 @@ VOID TEST(ConfigDirectiveTest, ParseInvalidEmptyDirective) EXPECT_EQ(0, (int)dir0.args.size()); EXPECT_EQ(0, (int)dir0.directives.size()); } + +VOID TEST(ConfigDirectiveTest, ParseLine) +{ + MockSrsConfigBuffer buf("dir0 {}"); + SrsConfDirective conf; + EXPECT_TRUE(ERROR_SUCCESS == conf.parse(&buf)); + EXPECT_EQ(0, (int)conf.name.length()); + EXPECT_EQ(0, (int)conf.args.size()); + EXPECT_EQ(1, (int)conf.directives.size()); + + SrsConfDirective& dir0 = *conf.directives.at(0); + EXPECT_STREQ("dir0", dir0.name.c_str()); + EXPECT_EQ(0, (int)dir0.args.size()); + EXPECT_EQ(0, (int)dir0.directives.size()); + EXPECT_EQ(1, (int)dir0.conf_line); +} + +VOID TEST(ConfigDirectiveTest, ParseLine2) +{ + MockSrsConfigBuffer buf("\n\ndir0 {}"); + SrsConfDirective conf; + EXPECT_TRUE(ERROR_SUCCESS == conf.parse(&buf)); + EXPECT_EQ(0, (int)conf.name.length()); + EXPECT_EQ(0, (int)conf.args.size()); + EXPECT_EQ(1, (int)conf.directives.size()); + + SrsConfDirective& dir0 = *conf.directives.at(0); + EXPECT_STREQ("dir0", dir0.name.c_str()); + EXPECT_EQ(0, (int)dir0.args.size()); + EXPECT_EQ(0, (int)dir0.directives.size()); + EXPECT_EQ(3, (int)dir0.conf_line); +} + +VOID TEST(ConfigDirectiveTest, ParseLine3) +{ + MockSrsConfigBuffer buf("dir0 {\n\ndir1 arg0;}"); + SrsConfDirective conf; + EXPECT_TRUE(ERROR_SUCCESS == conf.parse(&buf)); + EXPECT_EQ(0, (int)conf.name.length()); + EXPECT_EQ(0, (int)conf.args.size()); + EXPECT_EQ(1, (int)conf.directives.size()); + + SrsConfDirective& dir0 = *conf.directives.at(0); + EXPECT_STREQ("dir0", dir0.name.c_str()); + EXPECT_EQ(0, (int)dir0.args.size()); + EXPECT_EQ(1, (int)dir0.directives.size()); + EXPECT_EQ(1, (int)dir0.conf_line); + + SrsConfDirective& dir1 = *dir0.directives.at(0); + EXPECT_STREQ("dir1", dir1.name.c_str()); + EXPECT_EQ(1, (int)dir1.args.size()); + EXPECT_STREQ("arg0", dir1.arg0().c_str()); + EXPECT_EQ(0, (int)dir1.directives.size()); + EXPECT_EQ(3, (int)dir1.conf_line); +} + +VOID TEST(ConfigDirectiveTest, ParseLine4) +{ + MockSrsConfigBuffer buf("dir0 {\n\ndir1 \n\narg0;dir2 arg1;}"); + SrsConfDirective conf; + EXPECT_TRUE(ERROR_SUCCESS == conf.parse(&buf)); + EXPECT_EQ(0, (int)conf.name.length()); + EXPECT_EQ(0, (int)conf.args.size()); + EXPECT_EQ(1, (int)conf.directives.size()); + + SrsConfDirective& dir0 = *conf.directives.at(0); + EXPECT_STREQ("dir0", dir0.name.c_str()); + EXPECT_EQ(0, (int)dir0.args.size()); + EXPECT_EQ(2, (int)dir0.directives.size()); + EXPECT_EQ(1, (int)dir0.conf_line); + + SrsConfDirective& dir1 = *dir0.directives.at(0); + EXPECT_STREQ("dir1", dir1.name.c_str()); + EXPECT_EQ(1, (int)dir1.args.size()); + EXPECT_STREQ("arg0", dir1.arg0().c_str()); + EXPECT_EQ(0, (int)dir1.directives.size()); + EXPECT_EQ(3, (int)dir1.conf_line); + + SrsConfDirective& dir2 = *dir0.directives.at(1); + EXPECT_STREQ("dir2", dir2.name.c_str()); + EXPECT_EQ(1, (int)dir2.args.size()); + EXPECT_STREQ("arg1", dir2.arg0().c_str()); + EXPECT_EQ(0, (int)dir2.directives.size()); + EXPECT_EQ(5, (int)dir2.conf_line); +} + +VOID TEST(ConfigDirectiveTest, ParseLineNormal) +{ + MockSrsConfigBuffer buf("dir0 {\ndir1 {\ndir2 arg2;\n}\n}"); + SrsConfDirective conf; + EXPECT_TRUE(ERROR_SUCCESS == conf.parse(&buf)); + EXPECT_EQ(0, (int)conf.name.length()); + EXPECT_EQ(0, (int)conf.args.size()); + EXPECT_EQ(1, (int)conf.directives.size()); + + SrsConfDirective& dir0 = *conf.directives.at(0); + EXPECT_STREQ("dir0", dir0.name.c_str()); + EXPECT_EQ(0, (int)dir0.args.size()); + EXPECT_EQ(1, (int)dir0.directives.size()); + EXPECT_EQ(1, (int)dir0.conf_line); + + SrsConfDirective& dir1 = *dir0.directives.at(0); + EXPECT_STREQ("dir1", dir1.name.c_str()); + EXPECT_EQ(0, (int)dir1.args.size()); + EXPECT_EQ(1, (int)dir1.directives.size()); + EXPECT_EQ(2, (int)dir1.conf_line); + + SrsConfDirective& dir2 = *dir1.directives.at(0); + EXPECT_STREQ("dir2", dir2.name.c_str()); + EXPECT_EQ(1, (int)dir2.args.size()); + EXPECT_STREQ("arg2", dir2.arg0().c_str()); + EXPECT_EQ(0, (int)dir2.directives.size()); + EXPECT_EQ(3, (int)dir2.conf_line); +}