Skip to content

Commit 4a41d29

Browse files
committed
Have parse_stream handle NUL bytes
1 parent b167189 commit 4a41d29

File tree

3 files changed

+16
-5
lines changed

3 files changed

+16
-5
lines changed

ext/prism/extension.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -856,8 +856,8 @@ parse_stream_fgets(char *string, int size, void *stream) {
856856
return NULL;
857857
}
858858

859-
const char *cstr = StringValueCStr(line);
860-
size_t length = strlen(cstr);
859+
const char *cstr = RSTRING_PTR(line);
860+
long length = RSTRING_LEN(line);
861861

862862
memcpy(string, cstr, length);
863863
string[length] = '\0';

src/prism.c

+6-3
Original file line numberDiff line numberDiff line change
@@ -21696,18 +21696,21 @@ pm_parse_stream_read(pm_buffer_t *buffer, void *stream, pm_parse_stream_fgets_t
2169621696
#define LINE_SIZE 4096
2169721697
char line[LINE_SIZE];
2169821698

21699-
while (fgets(line, LINE_SIZE, stream) != NULL) {
21700-
size_t length = strlen(line);
21699+
while (memset(line, '\n', LINE_SIZE), fgets(line, LINE_SIZE, stream) != NULL) {
21700+
size_t length = LINE_SIZE;
21701+
while (length > 0 && line[length - 1] == '\n') length--;
2170121702

21702-
if (length == LINE_SIZE && line[length - 1] != '\n') {
21703+
if (length == LINE_SIZE) {
2170321704
// If we read a line that is the maximum size and it doesn't end
2170421705
// with a newline, then we'll just append it to the buffer and
2170521706
// continue reading.
21707+
length--;
2170621708
pm_buffer_append_string(buffer, line, length);
2170721709
continue;
2170821710
}
2170921711

2171021712
// Append the line to the buffer.
21713+
length--;
2171121714
pm_buffer_append_string(buffer, line, length);
2171221715

2171321716
// Check if the line matches the __END__ marker. If it does, then stop

test/prism/api/parse_stream_test.rb

+8
Original file line numberDiff line numberDiff line change
@@ -69,5 +69,13 @@ def test_false___END___in_heredoc
6969
assert result.success?
7070
assert_equal 4, result.value.statements.body.length
7171
end
72+
73+
def test_nul_bytes
74+
io = StringIO.new("1 # \0\0\0 \n2 # \0\0\0\n3")
75+
result = Prism.parse_stream(io)
76+
77+
assert result.success?
78+
assert_equal 3, result.value.statements.body.length
79+
end
7280
end
7381
end

0 commit comments

Comments
 (0)