ruby-changes:32737
From: nobu <ko1@a...>
Date: Wed, 5 Feb 2014 10:17:31 +0900 (JST)
Subject: [ruby-changes:32737] nobu:r44816 (trunk): yaml/api.c, yaml/loader.c: integer overflow
nobu 2014-02-05 10:17:28 +0900 (Wed, 05 Feb 2014) New Revision: 44816 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=44816 Log: yaml/api.c, yaml/loader.c: integer overflow * ext/psych/yaml/api.c (yaml_scalar_event_initialize): fix possible integer overflow. (yaml_document_add_scalar): ditto. (yaml_document_add_sequence): ditto. (yaml_document_add_mapping): ditto. * ext/psych/yaml/loader.c (yaml_parser_load_scalar): ditto. (yaml_parser_load_sequence): ditto. (yaml_parser_load_mapping): ditto. * ext/psych/yaml/scanner.c (yaml_parser_roll_indent): suppress warnigs. Modified files: trunk/ext/psych/yaml/api.c trunk/ext/psych/yaml/loader.c trunk/ext/psych/yaml/scanner.c Index: ext/psych/yaml/loader.c =================================================================== --- ext/psych/yaml/loader.c (revision 44815) +++ ext/psych/yaml/loader.c (revision 44816) @@ -283,6 +283,7 @@ static int https://github.com/ruby/ruby/blob/trunk/ext/psych/yaml/loader.c#L283 yaml_parser_load_scalar(yaml_parser_t *parser, yaml_event_t *first_event) { yaml_node_t node; + ptrdiff_t node_index; int index; yaml_char_t *tag = first_event->data.scalar.tag; @@ -300,7 +301,11 @@ yaml_parser_load_scalar(yaml_parser_t *p https://github.com/ruby/ruby/blob/trunk/ext/psych/yaml/loader.c#L301 if (!PUSH(parser, parser->document->nodes, node)) goto error; - index = parser->document->nodes.top - parser->document->nodes.start; + node_index = parser->document->nodes.top - parser->document->nodes.start; +#if PTRDIFF_MAX > INT_MAX + if (node_index > INT_MAX) goto error; +#endif + index = (int)node_index; if (!yaml_parser_register_anchor(parser, index, first_event->data.scalar.anchor)) return 0; @@ -329,6 +334,7 @@ yaml_parser_load_sequence(yaml_parser_t https://github.com/ruby/ruby/blob/trunk/ext/psych/yaml/loader.c#L334 yaml_node_item_t *top; } items = { NULL, NULL, NULL }; int index, item_index; + ptrdiff_t node_index; yaml_char_t *tag = first_event->data.sequence_start.tag; if (!STACK_LIMIT(parser, parser->document->nodes, INT_MAX-1)) goto error; @@ -347,7 +353,11 @@ yaml_parser_load_sequence(yaml_parser_t https://github.com/ruby/ruby/blob/trunk/ext/psych/yaml/loader.c#L353 if (!PUSH(parser, parser->document->nodes, node)) goto error; - index = parser->document->nodes.top - parser->document->nodes.start; + node_index = parser->document->nodes.top - parser->document->nodes.start; +#if PTRDIFF_MAX > INT_MAX + if (node_index > INT_MAX) goto error; +#endif + index = (int)node_index; if (!yaml_parser_register_anchor(parser, index, first_event->data.sequence_start.anchor)) return 0; @@ -391,6 +401,7 @@ yaml_parser_load_mapping(yaml_parser_t * https://github.com/ruby/ruby/blob/trunk/ext/psych/yaml/loader.c#L401 yaml_node_pair_t *top; } pairs = { NULL, NULL, NULL }; int index; + ptrdiff_t node_index; yaml_node_pair_t pair; yaml_char_t *tag = first_event->data.mapping_start.tag; @@ -410,7 +421,11 @@ yaml_parser_load_mapping(yaml_parser_t * https://github.com/ruby/ruby/blob/trunk/ext/psych/yaml/loader.c#L421 if (!PUSH(parser, parser->document->nodes, node)) goto error; - index = parser->document->nodes.top - parser->document->nodes.start; + node_index = parser->document->nodes.top - parser->document->nodes.start; +#if PTRDIFF_MAX > INT_MAX + if (node_index > INT_MAX) goto error; +#endif + index = (int)node_index; if (!yaml_parser_register_anchor(parser, index, first_event->data.mapping_start.anchor)) return 0; Index: ext/psych/yaml/api.c =================================================================== --- ext/psych/yaml/api.c (revision 44815) +++ ext/psych/yaml/api.c (revision 44816) @@ -822,6 +822,7 @@ yaml_scalar_event_initialize(yaml_event_ https://github.com/ruby/ruby/blob/trunk/ext/psych/yaml/api.c#L822 yaml_char_t *anchor_copy = NULL; yaml_char_t *tag_copy = NULL; yaml_char_t *value_copy = NULL; + size_t value_length; assert(event); /* Non-NULL event object is expected. */ assert(value); /* Non-NULL anchor is expected. */ @@ -839,16 +840,19 @@ yaml_scalar_event_initialize(yaml_event_ https://github.com/ruby/ruby/blob/trunk/ext/psych/yaml/api.c#L840 } if (length < 0) { - length = strlen((char *)value); + value_length = strlen((char *)value); + } + else { + value_length = (size_t)length; } - if (!yaml_check_utf8(value, length)) goto error; - value_copy = yaml_malloc(length+1); + if (!yaml_check_utf8(value, value_length)) goto error; + value_copy = yaml_malloc(value_length+1); if (!value_copy) goto error; - memcpy(value_copy, value, length); - value_copy[length] = '\0'; + memcpy(value_copy, value, value_length); + value_copy[value_length] = '\0'; - SCALAR_EVENT_INIT(*event, anchor_copy, tag_copy, value_copy, length, + SCALAR_EVENT_INIT(*event, anchor_copy, tag_copy, value_copy, value_length, plain_implicit, quoted_implicit, style, mark, mark); return 1; @@ -1202,6 +1206,8 @@ yaml_document_add_scalar(yaml_document_t https://github.com/ruby/ruby/blob/trunk/ext/psych/yaml/api.c#L1206 yaml_char_t *tag_copy = NULL; yaml_char_t *value_copy = NULL; yaml_node_t node; + size_t value_length; + ptrdiff_t ret; assert(document); /* Non-NULL document object is expected. */ assert(value); /* Non-NULL value is expected. */ @@ -1215,19 +1221,26 @@ yaml_document_add_scalar(yaml_document_t https://github.com/ruby/ruby/blob/trunk/ext/psych/yaml/api.c#L1221 if (!tag_copy) goto error; if (length < 0) { - length = strlen((char *)value); + value_length = strlen((char *)value); + } + else { + value_length = (size_t)length; } - if (!yaml_check_utf8(value, length)) goto error; - value_copy = yaml_malloc(length+1); + if (!yaml_check_utf8(value, value_length)) goto error; + value_copy = yaml_malloc(value_length+1); if (!value_copy) goto error; - memcpy(value_copy, value, length); - value_copy[length] = '\0'; + memcpy(value_copy, value, value_length); + value_copy[value_length] = '\0'; - SCALAR_NODE_INIT(node, tag_copy, value_copy, length, style, mark, mark); + SCALAR_NODE_INIT(node, tag_copy, value_copy, value_length, style, mark, mark); if (!PUSH(&context, document->nodes, node)) goto error; - return document->nodes.top - document->nodes.start; + ret = document->nodes.top - document->nodes.start; +#if PTRDIFF_MAX > INT_MAX + if (ret > INT_MAX) goto error; +#endif + return (int)ret; error: yaml_free(tag_copy); @@ -1255,6 +1268,7 @@ yaml_document_add_sequence(yaml_document https://github.com/ruby/ruby/blob/trunk/ext/psych/yaml/api.c#L1268 yaml_node_item_t *top; } items = { NULL, NULL, NULL }; yaml_node_t node; + ptrdiff_t ret; assert(document); /* Non-NULL document object is expected. */ @@ -1272,7 +1286,11 @@ yaml_document_add_sequence(yaml_document https://github.com/ruby/ruby/blob/trunk/ext/psych/yaml/api.c#L1286 style, mark, mark); if (!PUSH(&context, document->nodes, node)) goto error; - return document->nodes.top - document->nodes.start; + ret = document->nodes.top - document->nodes.start; +#if PTRDIFF_MAX > INT_MAX + if (ret > INT_MAX) goto error; +#endif + return (int)ret; error: STACK_DEL(&context, items); @@ -1300,6 +1318,7 @@ yaml_document_add_mapping(yaml_document_ https://github.com/ruby/ruby/blob/trunk/ext/psych/yaml/api.c#L1318 yaml_node_pair_t *top; } pairs = { NULL, NULL, NULL }; yaml_node_t node; + ptrdiff_t ret; assert(document); /* Non-NULL document object is expected. */ @@ -1317,7 +1336,11 @@ yaml_document_add_mapping(yaml_document_ https://github.com/ruby/ruby/blob/trunk/ext/psych/yaml/api.c#L1336 style, mark, mark); if (!PUSH(&context, document->nodes, node)) goto error; - return document->nodes.top - document->nodes.start; + ret = document->nodes.top - document->nodes.start; +#if PTRDIFF_MAX > INT_MAX + if (ret > INT_MAX) goto error; +#endif + return (int)ret; error: STACK_DEL(&context, pairs); Index: ext/psych/yaml/scanner.c =================================================================== --- ext/psych/yaml/scanner.c (revision 44815) +++ ext/psych/yaml/scanner.c (revision 44816) @@ -1231,12 +1231,14 @@ yaml_parser_roll_indent(yaml_parser_t *p https://github.com/ruby/ruby/blob/trunk/ext/psych/yaml/scanner.c#L1231 if (!PUSH(parser, parser->indents, parser->indent)) return 0; +#if PTRDIFF_MAX > INT_MAX if (column > INT_MAX) { parser->error = YAML_MEMORY_ERROR; return 0; } +#endif - parser->indent = column; + parser->indent = (int)column; /* Create a token and insert it into the queue. */ -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/