diff --git a/common.h b/common.h index 5c4629740..4eb17bf09 100644 --- a/common.h +++ b/common.h @@ -59,6 +59,9 @@ typedef std::vector wcstring_list_t; */ #define BYTE_MAX 0xffu +/** BOM value */ +#define UTF8_BOM_WCHAR 0xFEFFu + /* Flags for unescape_string functions */ enum { diff --git a/reader.cpp b/reader.cpp index ecf42bb30..84c364972 100644 --- a/reader.cpp +++ b/reader.cpp @@ -4205,7 +4205,7 @@ static int read_ni(int fd, const io_chain_t &io) acc.insert(acc.end(), buff, buff + c); } - const wcstring str = acc.empty() ? wcstring() : str2wcstring(&acc.at(0), acc.size()); + wcstring str = acc.empty() ? wcstring() : str2wcstring(&acc.at(0), acc.size()); acc.clear(); if (fclose(in_stream)) @@ -4216,6 +4216,12 @@ static int read_ni(int fd, const io_chain_t &io) res = 1; } + /* Swallow a BOM (#1518) */ + if (! str.empty() && str.at(0) == UTF8_BOM_WCHAR) + { + str.erase(0, 1); + } + parse_error_list_t errors; if (! parse_util_detect_errors(str, &errors, false /* do not accept incomplete */)) { diff --git a/tests/test9.in b/tests/test9.in index e5b694859..e85c64b11 100644 --- a/tests/test9.in +++ b/tests/test9.in @@ -113,4 +113,7 @@ try_unbalanced_block 'if false' "while" false; end "wh"'ile' false; "e"nd +# BOM checking (see #1518) +echo \uFEFF"echo bom_test" | source + false diff --git a/tests/test9.out b/tests/test9.out index 2e8e8bc7e..9fe347de4 100644 --- a/tests/test9.out +++ b/tests/test9.out @@ -17,3 +17,4 @@ foo bar baz psub file was deleted +bom_test