Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 30 additions & 15 deletions ext/psych/psych_emitter.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,8 @@ static VALUE start_stream(VALUE self, VALUE encoding)
TypedData_Get_Struct(self, yaml_emitter_t, &psych_emitter_type, emitter);
Check_Type(encoding, T_FIXNUM);

yaml_stream_start_event_initialize(&event, (yaml_encoding_t)NUM2INT(encoding));
if(!yaml_stream_start_event_initialize(&event, (yaml_encoding_t)NUM2INT(encoding)))
rb_raise(rb_eRuntimeError, "failed to initialize stream start event");

emit(emitter, &event);

Expand All @@ -131,7 +132,8 @@ static VALUE end_stream(VALUE self)
yaml_event_t event;
TypedData_Get_Struct(self, yaml_emitter_t, &psych_emitter_type, emitter);

yaml_stream_end_event_initialize(&event);
if(!yaml_stream_end_event_initialize(&event))
rb_raise(rb_eRuntimeError, "failed to initialize stream end event");

emit(emitter, &event);

Expand Down Expand Up @@ -207,13 +209,15 @@ static VALUE start_document_try(VALUE d)
}
}

yaml_document_start_event_initialize(
if(!yaml_document_start_event_initialize(
&event,
(RARRAY_LEN(version) > 0) ? &version_directive : NULL,
data->head,
tail,
imp ? 1 : 0
);
)) {
rb_raise(rb_eRuntimeError, "failed to initialize document start event");
}

emit(emitter, &event);

Expand Down Expand Up @@ -262,7 +266,8 @@ static VALUE end_document(VALUE self, VALUE imp)
yaml_event_t event;
TypedData_Get_Struct(self, yaml_emitter_t, &psych_emitter_type, emitter);

yaml_document_end_event_initialize(&event, imp ? 1 : 0);
if(!yaml_document_end_event_initialize(&event, imp ? 1 : 0))
rb_raise(rb_eRuntimeError, "failed to initialize document end event");

emit(emitter, &event);

Expand Down Expand Up @@ -307,7 +312,7 @@ static VALUE scalar(
}

const char *value_ptr = StringValuePtr(value);
yaml_scalar_event_initialize(
if(!yaml_scalar_event_initialize(
&event,
(yaml_char_t *)(NIL_P(anchor) ? NULL : StringValueCStr(anchor)),
(yaml_char_t *)(NIL_P(tag) ? NULL : StringValueCStr(tag)),
Expand All @@ -316,7 +321,9 @@ static VALUE scalar(
plain ? 1 : 0,
quoted ? 1 : 0,
(yaml_scalar_style_t)NUM2INT(style)
);
)) {
rb_raise(rb_eRuntimeError, "failed to initialize scalar event");
}

emit(emitter, &event);

Expand Down Expand Up @@ -354,13 +361,15 @@ static VALUE start_sequence(

TypedData_Get_Struct(self, yaml_emitter_t, &psych_emitter_type, emitter);

yaml_sequence_start_event_initialize(
if(!yaml_sequence_start_event_initialize(
&event,
(yaml_char_t *)(NIL_P(anchor) ? NULL : StringValueCStr(anchor)),
(yaml_char_t *)(NIL_P(tag) ? NULL : StringValueCStr(tag)),
implicit ? 1 : 0,
(yaml_sequence_style_t)NUM2INT(style)
);
)) {
rb_raise(rb_eRuntimeError, "failed to initialize sequence start event");
}

emit(emitter, &event);

Expand All @@ -379,7 +388,8 @@ static VALUE end_sequence(VALUE self)
yaml_event_t event;
TypedData_Get_Struct(self, yaml_emitter_t, &psych_emitter_type, emitter);

yaml_sequence_end_event_initialize(&event);
if(!yaml_sequence_end_event_initialize(&event))
rb_raise(rb_eRuntimeError, "failed to initialize sequence end event");

emit(emitter, &event);

Expand Down Expand Up @@ -418,13 +428,15 @@ static VALUE start_mapping(
tag = rb_str_export_to_enc(tag, encoding);
}

yaml_mapping_start_event_initialize(
if(!yaml_mapping_start_event_initialize(
&event,
(yaml_char_t *)(NIL_P(anchor) ? NULL : StringValueCStr(anchor)),
(yaml_char_t *)(NIL_P(tag) ? NULL : StringValueCStr(tag)),
implicit ? 1 : 0,
(yaml_mapping_style_t)NUM2INT(style)
);
)) {
rb_raise(rb_eRuntimeError, "failed to initialize mapping start event");
}

emit(emitter, &event);

Expand All @@ -443,7 +455,8 @@ static VALUE end_mapping(VALUE self)
yaml_event_t event;
TypedData_Get_Struct(self, yaml_emitter_t, &psych_emitter_type, emitter);

yaml_mapping_end_event_initialize(&event);
if(!yaml_mapping_end_event_initialize(&event))
rb_raise(rb_eRuntimeError, "failed to initialize mapping end event");

emit(emitter, &event);

Expand All @@ -467,10 +480,12 @@ static VALUE alias(VALUE self, VALUE anchor)
anchor = rb_str_export_to_enc(anchor, rb_utf8_encoding());
}

yaml_alias_event_initialize(
if(!yaml_alias_event_initialize(
&event,
(yaml_char_t *)(NIL_P(anchor) ? NULL : StringValueCStr(anchor))
);
)) {
rb_raise(rb_eRuntimeError, "failed to initialize alias event");
}

emit(emitter, &event);

Expand Down
7 changes: 7 additions & 0 deletions test/psych/helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,13 @@ def libfyaml?
defined?(Psych::BACKEND) && Psych::BACKEND == 'libfyaml'
end

# True when psych uses the default libyaml C backend (not libfyaml and
# not the JRuby backend, both of which leave Psych::BACKEND either set to
# a different value or undefined).
def libyaml?
defined?(Psych::BACKEND) && Psych::BACKEND == 'libyaml'
end

def with_default_external(enc)
verbose, $VERBOSE = $VERBOSE, nil
origenc, Encoding.default_external = Encoding.default_external, enc
Expand Down
39 changes: 39 additions & 0 deletions test/psych/test_emitter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,45 @@ def test_start_sequence_arg_error
end
end

def test_invalid_event
omit 'libyaml backend only' unless libyaml?

invalid = "\xFF"

bad_calls = [
->(e) { e.scalar(invalid, nil, nil, false, true, 1) },
->(e) { e.scalar('x', invalid, nil, false, true, 1) },
->(e) { e.scalar('x', nil, invalid, false, true, 1) },
->(e) { e.start_sequence(invalid, nil, false, 1) },
->(e) { e.start_sequence(nil, invalid, false, 1) },
->(e) { e.start_mapping(invalid, nil, false, 1) },
->(e) { e.start_mapping(nil, invalid, false, 1) },
->(e) { e.alias(invalid) },
]

bad_calls.each do |bad_call|
out = StringIO.new(''.dup)
emitter = Psych::Emitter.new out
emitter.start_stream Psych::Nodes::Stream::UTF8
emitter.start_document [], [], true
# Emit a valid event that allocates memory (its anchor and tag).
emitter.start_sequence 'anchor', 'tag:example.com,2000:seq', false, 1

assert_raise(RuntimeError) { bad_call.call(emitter) }
end
end

def test_invalid_tag_directive
omit 'libyaml backend only' unless libyaml?

invalid = "\xFF"

@emitter.start_stream Psych::Nodes::Stream::UTF8
assert_raise(RuntimeError) do
@emitter.start_document [1, 1], [[invalid, 'tag:x']], false
end
end

def test_resizing_tags
@emitter.start_stream Psych::Nodes::Stream::UTF8

Expand Down
Loading