New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Handle BOM in the beginning of the script #439
Changes from 19 commits
f37d0e1
1d78233
1e8f7f9
efbebee
a024db0
c09af92
322568b
0d44b0b
60c0a0b
b70a9e7
be29b0a
d880d46
f9615ef
df6bc8f
67dcd3e
4ada12a
ac10575
edadb7a
51bb793
51693aa
0e964da
42c355a
1711d50
393f8d3
fb63503
0f67b2f
b3f77f0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -204,6 +204,27 @@ namespace chaiscript | |
m_engine.add(fun([this](const std::string& t_namespace_name) { import(t_namespace_name); }), "import"); | ||
} | ||
|
||
/// Skip BOM at the beginning of file | ||
static bool skip_bom(std::ifstream &infile) { | ||
std::streamsize bytes_needed = 3; | ||
std::streamsize bytes_read = 0; | ||
char buffer[3] = { '\0' }; | ||
|
||
bytes_read = infile.readsome(buffer, bytes_needed); | ||
|
||
if (bytes_needed == bytes_read | ||
&& (buffer[0] == '\xef') | ||
&& (buffer[1] == '\xbb') | ||
&& (buffer[2] == '\xbf')) { | ||
|
||
infile.seekg(3); | ||
return true; | ||
} | ||
|
||
infile.seekg(0); | ||
|
||
return false; | ||
} | ||
|
||
/// Helper function for loading a file | ||
static std::string load_file(const std::string &t_filename) { | ||
|
@@ -213,11 +234,16 @@ namespace chaiscript | |
throw chaiscript::exception::file_not_found_error(t_filename); | ||
} | ||
|
||
const auto size = infile.tellg(); | ||
auto size = infile.tellg(); | ||
infile.seekg(0, std::ios::beg); | ||
|
||
assert(size >= 0); | ||
|
||
if (skip_bom(infile)) { | ||
size-=3; // decrement the BOM size from file size, otherwise we'll get parsing errors | ||
assert(size >=0 ); //and check if there's more text | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd probably do another |
||
|
||
if (size == std::streampos(0)) | ||
{ | ||
return std::string(); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -352,7 +352,29 @@ TEST_CASE("Functor cast") | |
CHECK(d == 3 * 6); | ||
} | ||
|
||
TEST_CASE("Non-ASCII characters in the middle of string") | ||
{ | ||
chaiscript::ChaiScript_Basic chai(create_chaiscript_stdlib(),create_chaiscript_parser()); | ||
CHECK_THROWS_AS(chai.eval<std::string>("prin\xeft \"Hello World\""), chaiscript::exception::eval_error); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You misunderstood me. I think there should be at least three test cases, I could even imagine five:
|
||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Still needs a test case for other binary/non-ANSI garbage in the input at random positions (beginning, middle, end). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I left just one non-ASCII character and moved it to the middle of the string. |
||
|
||
TEST_CASE("Non-ASCII characters in the beginning of string") | ||
{ | ||
chaiscript::ChaiScript_Basic chai(create_chaiscript_stdlib(),create_chaiscript_parser()); | ||
CHECK_THROWS_AS(chai.eval<std::string>("\xefprint \"Hello World\""), chaiscript::exception::eval_error); | ||
} | ||
|
||
TEST_CASE("Non-ASCII characters in the end of string") | ||
{ | ||
chaiscript::ChaiScript_Basic chai(create_chaiscript_stdlib(),create_chaiscript_parser()); | ||
CHECK_THROWS_AS(chai.eval<std::string>("print \"Hello World\"\xef"), chaiscript::exception::eval_error); | ||
} | ||
|
||
TEST_CASE("BOM in string") | ||
{ | ||
chaiscript::ChaiScript_Basic chai(create_chaiscript_stdlib(),create_chaiscript_parser()); | ||
CHECK_THROWS_AS(chai.eval<std::string>("\xef\xbb\xbfprint \"Hello World\""), chaiscript::exception::eval_error); | ||
} | ||
|
||
int set_state_test_myfun() | ||
{ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
eval_file("file_with_bom.inc") | ||
assert_true(alwaysTrue()) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
def alwaysTrue() { | ||
return true | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You don't have to initialize the array elements to
\0
if you check length anyway. This was more an idea in case you just do the three comparisons only and skip the length check.But besides that, nothing more to comment on. :)