| 821 | } |
| 822 | |
| 823 | Token Scanner::scanString(bool const _isUnicode) |
| 824 | { |
| 825 | size_t startPosition = m_source.position(); |
| 826 | char const quote = m_char; |
| 827 | advance(); // consume quote |
| 828 | LiteralScope literal(this, LITERAL_TYPE_STRING); |
| 829 | // for source location comments we allow multiline string literals |
| 830 | while (m_char != quote && !isSourcePastEndOfInput() && (!isUnicodeLinebreak() || m_kind == ScannerKind::SpecialComment)) |
| 831 | { |
| 832 | char c = m_char; |
| 833 | advance(); |
| 834 | |
| 835 | if (m_kind == ScannerKind::SpecialComment) |
| 836 | { |
| 837 | if (c == '\\') |
| 838 | { |
| 839 | if (isSourcePastEndOfInput()) |
| 840 | return setError(ScannerError::IllegalEscapeSequence); |
| 841 | advance(); |
| 842 | } |
| 843 | else |
| 844 | addLiteralChar(c); |
| 845 | } |
| 846 | else |
| 847 | { |
| 848 | if (c == '\\') |
| 849 | { |
| 850 | if (isSourcePastEndOfInput() || !scanEscape()) |
| 851 | return setError(ScannerError::IllegalEscapeSequence); |
| 852 | } |
| 853 | else |
| 854 | { |
| 855 | // Report error on non-printable characters in string literals, however |
| 856 | // allow anything for unicode string literals, because their validity will |
| 857 | // be verified later (in the syntax checker). |
| 858 | // |
| 859 | // We are using a manual range and not isprint() to avoid |
| 860 | // any potential complications with locale. |
| 861 | if (!_isUnicode && (static_cast<unsigned>(c) <= 0x1f || static_cast<unsigned>(c) >= 0x7f)) |
| 862 | { |
| 863 | if (m_kind == ScannerKind::Yul) |
| 864 | return setError(ScannerError::IllegalCharacterInString); |
| 865 | return setError(ScannerError::UnicodeCharacterInNonUnicodeString); |
| 866 | } |
| 867 | addLiteralChar(c); |
| 868 | } |
| 869 | } |
| 870 | |
| 871 | } |
| 872 | if (m_char != quote) |
| 873 | return setError(ScannerError::IllegalStringEndQuote); |
| 874 | |
| 875 | if (_isUnicode) |
| 876 | { |
| 877 | ScannerError unicodeDirectionError = validateBiDiMarkup(m_source, startPosition); |
| 878 | if (unicodeDirectionError != ScannerError::NoError) |
| 879 | return setError(unicodeDirectionError); |
| 880 | } |
nothing calls this directly
no test coverage detected