~ubuntu-branches/ubuntu/raring/ruby1.9.1/raring-security

« back to all changes in this revision

Viewing changes to ext/psych/parser.c

  • Committer: Package Import Robot
  • Author(s): Antonio Terceiro, Lucas Nussbaum, Daigo Moriwaki, James Healy, Antonio Terceiro
  • Date: 2012-06-02 07:42:28 UTC
  • mfrom: (21.1.3 sid)
  • Revision ID: package-import@ubuntu.com-20120602074228-09t2jgg1ozrsnnfo
Tags: 1.9.3.194-1
[ Lucas Nussbaum ]
* Add hurd-path-max.diff. Fixes FTBFS on Hurd. (Closes: #648055)

[ Daigo Moriwaki ]
* Removed debian/patches/debian/patches/sparc-continuations.diff,
  which the upstream has applied.
* debian/rules:
  - Bumped up tcltk_ver to 8.5.
  - Used chrpath for tcltklib.so to fix a lintian error,
    binary-or-shlib-defines-rpath.
* debian/control:
  - Suggests ruby-switch. (Closes: #654312)
  - Build-Depends: chrpath.
* debian/libruby1.9.1.symbols: Added a new symbol for
  rb_str_modify_expand@Base.
* debian/run-test-suites.bash:
  - Corrected options for test-all.
  - Enabled timeout to allow hang tests to be aborted.

[ James Healy ]
* New upstream release: 1.9.3p194 (Closes: #669582)
  + This release includes a fix for CVE-2011-0188 (Closes: #628451)
  + This release also does not segfault when running the test suite under
    amd64 (Closes: #674347)
* Enable hardened build flags (Closes: #667964)
* debian/control:
  - depend on specific version on coreutils
  - update policy version (no changes)

[ Antonio Terceiro ]
* debian/ruby1.9.1.postinst:
  + bump alternatives priority for `ruby` to 51 so that Ruby 1.9 has a
    higher priority than Ruby 1.8 (50).
  + bump alternatives priority for `gem` to 181 so that the Rubygems
    provided by Ruby 1.9 has priority over the one provided by the rubygems
    package.
* debian/control: added myself to Uploaders:
* debian/libruby1.9.1.symbols: update with new symbols added in 1.9.3p194
  upstream release.
* debian/manpages/*: fix references to command names with s/1.9/1.9.1/
* debian/rules: skip running DRB tests, since they seem to make the build
  hang. This should close #647296, but let's way and see. Also, with this do
  not need to timeout the test suite anymore.

Show diffs side-by-side

added added

removed removed

Lines of Context:
59
59
    return Data_Wrap_Struct(klass, 0, dealloc, parser);
60
60
}
61
61
 
 
62
static VALUE make_exception(yaml_parser_t * parser, VALUE path)
 
63
{
 
64
    size_t line, column;
 
65
 
 
66
    line = parser->context_mark.line + 1;
 
67
    column = parser->context_mark.column + 1;
 
68
 
 
69
    return rb_funcall(ePsychSyntaxError, rb_intern("new"), 6,
 
70
            path,
 
71
            INT2NUM(line),
 
72
            INT2NUM(column),
 
73
            INT2NUM(parser->problem_offset),
 
74
            parser->problem ? rb_usascii_str_new2(parser->problem) : Qnil,
 
75
            parser->context ? rb_usascii_str_new2(parser->context) : Qnil);
 
76
}
 
77
 
 
78
#ifdef HAVE_RUBY_ENCODING_H
 
79
static VALUE transcode_string(VALUE src, int * parser_encoding)
 
80
{
 
81
    int utf8    = rb_utf8_encindex();
 
82
    int utf16le = rb_enc_find_index("UTF16_LE");
 
83
    int utf16be = rb_enc_find_index("UTF16_BE");
 
84
    int source_encoding = rb_enc_get_index(src);
 
85
 
 
86
    if (source_encoding == utf8) {
 
87
        *parser_encoding = YAML_UTF8_ENCODING;
 
88
        return src;
 
89
    }
 
90
 
 
91
    if (source_encoding == utf16le) {
 
92
        *parser_encoding = YAML_UTF16LE_ENCODING;
 
93
        return src;
 
94
    }
 
95
 
 
96
    if (source_encoding == utf16be) {
 
97
        *parser_encoding = YAML_UTF16BE_ENCODING;
 
98
        return src;
 
99
    }
 
100
 
 
101
    src = rb_str_export_to_enc(src, rb_utf8_encoding());
 
102
    RB_GC_GUARD(src);
 
103
 
 
104
    *parser_encoding = YAML_UTF8_ENCODING;
 
105
    return src;
 
106
}
 
107
 
 
108
static VALUE transcode_io(VALUE src, int * parser_encoding)
 
109
{
 
110
    VALUE io_external_encoding;
 
111
    int io_external_enc_index;
 
112
 
 
113
    io_external_encoding = rb_funcall(src, rb_intern("external_encoding"), 0);
 
114
 
 
115
    /* if no encoding is returned, assume ascii8bit. */
 
116
    if (NIL_P(io_external_encoding)) {
 
117
        io_external_enc_index = rb_ascii8bit_encindex();
 
118
    } else {
 
119
        io_external_enc_index = rb_to_encoding_index(io_external_encoding);
 
120
    }
 
121
 
 
122
    /* Treat US-ASCII as utf_8 */
 
123
    if (io_external_enc_index == rb_usascii_encindex()) {
 
124
        *parser_encoding = YAML_UTF8_ENCODING;
 
125
        return src;
 
126
    }
 
127
 
 
128
    if (io_external_enc_index == rb_utf8_encindex()) {
 
129
        *parser_encoding = YAML_UTF8_ENCODING;
 
130
        return src;
 
131
    }
 
132
 
 
133
    if (io_external_enc_index == rb_enc_find_index("UTF-16LE")) {
 
134
        *parser_encoding = YAML_UTF16LE_ENCODING;
 
135
        return src;
 
136
    }
 
137
 
 
138
    if (io_external_enc_index == rb_enc_find_index("UTF-16BE")) {
 
139
        *parser_encoding = YAML_UTF16BE_ENCODING;
 
140
        return src;
 
141
    }
 
142
 
 
143
    /* Just guess on ASCII-8BIT */
 
144
    if (io_external_enc_index == rb_ascii8bit_encindex()) {
 
145
        *parser_encoding = YAML_ANY_ENCODING;
 
146
        return src;
 
147
    }
 
148
 
 
149
    /* If the external encoding is something we don't know how to handle,
 
150
     * fall back to YAML_ANY_ENCODING. */
 
151
    *parser_encoding = YAML_ANY_ENCODING;
 
152
 
 
153
    return src;
 
154
}
 
155
 
 
156
#endif
 
157
 
 
158
static VALUE protected_start_stream(VALUE pointer)
 
159
{
 
160
    VALUE *args = (VALUE *)pointer;
 
161
    return rb_funcall(args[0], id_start_stream, 1, args[1]);
 
162
}
 
163
 
 
164
static VALUE protected_start_document(VALUE pointer)
 
165
{
 
166
    VALUE *args = (VALUE *)pointer;
 
167
    return rb_funcall3(args[0], id_start_document, 3, args + 1);
 
168
}
 
169
 
 
170
static VALUE protected_end_document(VALUE pointer)
 
171
{
 
172
    VALUE *args = (VALUE *)pointer;
 
173
    return rb_funcall(args[0], id_end_document, 1, args[1]);
 
174
}
 
175
 
 
176
static VALUE protected_alias(VALUE pointer)
 
177
{
 
178
    VALUE *args = (VALUE *)pointer;
 
179
    return rb_funcall(args[0], id_alias, 1, args[1]);
 
180
}
 
181
 
 
182
static VALUE protected_scalar(VALUE pointer)
 
183
{
 
184
    VALUE *args = (VALUE *)pointer;
 
185
    return rb_funcall3(args[0], id_scalar, 6, args + 1);
 
186
}
 
187
 
 
188
static VALUE protected_start_sequence(VALUE pointer)
 
189
{
 
190
    VALUE *args = (VALUE *)pointer;
 
191
    return rb_funcall3(args[0], id_start_sequence, 4, args + 1);
 
192
}
 
193
 
 
194
static VALUE protected_end_sequence(VALUE handler)
 
195
{
 
196
    return rb_funcall(handler, id_end_sequence, 0);
 
197
}
 
198
 
 
199
static VALUE protected_start_mapping(VALUE pointer)
 
200
{
 
201
    VALUE *args = (VALUE *)pointer;
 
202
    return rb_funcall3(args[0], id_start_mapping, 4, args + 1);
 
203
}
 
204
 
 
205
static VALUE protected_end_mapping(VALUE handler)
 
206
{
 
207
    return rb_funcall(handler, id_end_mapping, 0);
 
208
}
 
209
 
 
210
static VALUE protected_empty(VALUE handler)
 
211
{
 
212
    return rb_funcall(handler, id_empty, 0);
 
213
}
 
214
 
 
215
static VALUE protected_end_stream(VALUE handler)
 
216
{
 
217
    return rb_funcall(handler, id_end_stream, 0);
 
218
}
 
219
 
62
220
/*
63
221
 * call-seq:
64
222
 *    parser.parse(yaml)
68
226
 *
69
227
 * See Psych::Parser and Psych::Parser#handler
70
228
 */
71
 
static VALUE parse(VALUE self, VALUE yaml)
 
229
static VALUE parse(int argc, VALUE *argv, VALUE self)
72
230
{
 
231
    VALUE yaml, path;
73
232
    yaml_parser_t * parser;
74
233
    yaml_event_t event;
75
234
    int done = 0;
76
235
    int tainted = 0;
 
236
    int state = 0;
 
237
    int parser_encoding = YAML_ANY_ENCODING;
77
238
#ifdef HAVE_RUBY_ENCODING_H
78
239
    int encoding = rb_utf8_encindex();
79
240
    rb_encoding * internal_enc = rb_default_internal_encoding();
80
241
#endif
81
242
    VALUE handler = rb_iv_get(self, "@handler");
82
243
 
 
244
    if (rb_scan_args(argc, argv, "11", &yaml, &path) == 1) {
 
245
        if(rb_respond_to(yaml, id_path))
 
246
            path = rb_funcall(yaml, id_path, 0);
 
247
        else
 
248
            path = rb_str_new2("<unknown>");
 
249
    }
 
250
 
83
251
    Data_Get_Struct(self, yaml_parser_t, parser);
84
252
 
 
253
    yaml_parser_delete(parser);
 
254
    yaml_parser_initialize(parser);
 
255
 
85
256
    if (OBJ_TAINTED(yaml)) tainted = 1;
86
257
 
87
 
    if(rb_respond_to(yaml, id_read)) {
 
258
    if (rb_respond_to(yaml, id_read)) {
 
259
#ifdef HAVE_RUBY_ENCODING_H
 
260
        yaml = transcode_io(yaml, &parser_encoding);
 
261
        yaml_parser_set_encoding(parser, parser_encoding);
 
262
#endif
88
263
        yaml_parser_set_input(parser, io_reader, (void *)yaml);
89
264
        if (RTEST(rb_obj_is_kind_of(yaml, rb_cIO))) tainted = 1;
90
265
    } else {
91
266
        StringValue(yaml);
 
267
#ifdef HAVE_RUBY_ENCODING_H
 
268
        yaml = transcode_string(yaml, &parser_encoding);
 
269
        yaml_parser_set_encoding(parser, parser_encoding);
 
270
#endif
92
271
        yaml_parser_set_input_string(
93
272
                parser,
94
273
                (const unsigned char *)RSTRING_PTR(yaml),
98
277
 
99
278
    while(!done) {
100
279
        if(!yaml_parser_parse(parser, &event)) {
101
 
            VALUE path;
102
 
            size_t line   = parser->mark.line;
103
 
            size_t column = parser->mark.column;
104
 
 
105
 
            if(rb_respond_to(yaml, id_path))
106
 
                path = rb_funcall(yaml, id_path, 0);
107
 
            else
108
 
                path = rb_str_new2("<unknown>");
109
 
 
 
280
            VALUE exception;
 
281
 
 
282
            exception = make_exception(parser, path);
110
283
            yaml_parser_delete(parser);
111
284
            yaml_parser_initialize(parser);
112
285
 
113
 
            rb_raise(ePsychSyntaxError, "(%s): couldn't parse YAML at line %d column %d",
114
 
                    StringValuePtr(path),
115
 
                    (int)line, (int)column);
 
286
            rb_exc_raise(exception);
116
287
        }
117
288
 
118
289
        switch(event.type) {
119
 
          case YAML_STREAM_START_EVENT:
 
290
            case YAML_STREAM_START_EVENT:
 
291
              {
 
292
                  VALUE args[2];
120
293
 
121
 
            rb_funcall(handler, id_start_stream, 1,
122
 
                       INT2NUM((long)event.data.stream_start.encoding)
123
 
                );
124
 
            break;
 
294
                  args[0] = handler;
 
295
                  args[1] = INT2NUM((long)event.data.stream_start.encoding);
 
296
                  rb_protect(protected_start_stream, (VALUE)args, &state);
 
297
              }
 
298
              break;
125
299
          case YAML_DOCUMENT_START_EVENT:
126
300
            {
 
301
                VALUE args[4];
127
302
                /* Get a list of tag directives (if any) */
128
303
                VALUE tag_directives = rb_ary_new();
129
304
                /* Grab the document version */
161
336
                        rb_ary_push(tag_directives, rb_ary_new3((long)2, handle, prefix));
162
337
                    }
163
338
                }
164
 
                rb_funcall(handler, id_start_document, 3,
165
 
                           version, tag_directives,
166
 
                           event.data.document_start.implicit == 1 ? Qtrue : Qfalse
167
 
                    );
 
339
                args[0] = handler;
 
340
                args[1] = version;
 
341
                args[2] = tag_directives;
 
342
                args[3] = event.data.document_start.implicit == 1 ? Qtrue : Qfalse;
 
343
                rb_protect(protected_start_document, (VALUE)args, &state);
168
344
            }
169
345
            break;
170
346
          case YAML_DOCUMENT_END_EVENT:
171
 
            rb_funcall(handler, id_end_document, 1,
172
 
                       event.data.document_end.implicit == 1 ? Qtrue : Qfalse
173
 
                );
 
347
            {
 
348
                VALUE args[2];
 
349
 
 
350
                args[0] = handler;
 
351
                args[1] = event.data.document_end.implicit == 1 ? Qtrue : Qfalse;
 
352
                rb_protect(protected_end_document, (VALUE)args, &state);
 
353
            }
174
354
            break;
175
355
          case YAML_ALIAS_EVENT:
176
356
            {
 
357
                VALUE args[2];
177
358
                VALUE alias = Qnil;
178
359
                if(event.data.alias.anchor) {
179
360
                    alias = rb_str_new2((const char *)event.data.alias.anchor);
183
364
#endif
184
365
                }
185
366
 
186
 
                rb_funcall(handler, id_alias, 1, alias);
 
367
                args[0] = handler;
 
368
                args[1] = alias;
 
369
                rb_protect(protected_alias, (VALUE)args, &state);
187
370
            }
188
371
            break;
189
372
          case YAML_SCALAR_EVENT:
190
373
            {
 
374
                VALUE args[7];
191
375
                VALUE anchor = Qnil;
192
376
                VALUE tag = Qnil;
193
377
                VALUE plain_implicit, quoted_implicit, style;
225
409
 
226
410
                style = INT2NUM((long)event.data.scalar.style);
227
411
 
228
 
                rb_funcall(handler, id_scalar, 6,
229
 
                           val, anchor, tag, plain_implicit, quoted_implicit, style);
 
412
                args[0] = handler;
 
413
                args[1] = val;
 
414
                args[2] = anchor;
 
415
                args[3] = tag;
 
416
                args[4] = plain_implicit;
 
417
                args[5] = quoted_implicit;
 
418
                args[6] = style;
 
419
                rb_protect(protected_scalar, (VALUE)args, &state);
230
420
            }
231
421
            break;
232
422
          case YAML_SEQUENCE_START_EVENT:
233
423
            {
 
424
                VALUE args[5];
234
425
                VALUE anchor = Qnil;
235
426
                VALUE tag = Qnil;
236
427
                VALUE implicit, style;
256
447
 
257
448
                style = INT2NUM((long)event.data.sequence_start.style);
258
449
 
259
 
                rb_funcall(handler, id_start_sequence, 4,
260
 
                           anchor, tag, implicit, style);
 
450
                args[0] = handler;
 
451
                args[1] = anchor;
 
452
                args[2] = tag;
 
453
                args[3] = implicit;
 
454
                args[4] = style;
 
455
 
 
456
                rb_protect(protected_start_sequence, (VALUE)args, &state);
261
457
            }
262
458
            break;
263
459
          case YAML_SEQUENCE_END_EVENT:
264
 
            rb_funcall(handler, id_end_sequence, 0);
 
460
            rb_protect(protected_end_sequence, handler, &state);
265
461
            break;
266
462
          case YAML_MAPPING_START_EVENT:
267
463
            {
 
464
                VALUE args[5];
268
465
                VALUE anchor = Qnil;
269
466
                VALUE tag = Qnil;
270
467
                VALUE implicit, style;
289
486
 
290
487
                style = INT2NUM((long)event.data.mapping_start.style);
291
488
 
292
 
                rb_funcall(handler, id_start_mapping, 4,
293
 
                           anchor, tag, implicit, style);
 
489
                args[0] = handler;
 
490
                args[1] = anchor;
 
491
                args[2] = tag;
 
492
                args[3] = implicit;
 
493
                args[4] = style;
 
494
 
 
495
                rb_protect(protected_start_mapping, (VALUE)args, &state);
294
496
            }
295
497
            break;
296
498
          case YAML_MAPPING_END_EVENT:
297
 
            rb_funcall(handler, id_end_mapping, 0);
 
499
            rb_protect(protected_end_mapping, handler, &state);
298
500
            break;
299
501
          case YAML_NO_EVENT:
300
 
            rb_funcall(handler, id_empty, 0);
 
502
            rb_protect(protected_empty, handler, &state);
301
503
            break;
302
504
          case YAML_STREAM_END_EVENT:
303
 
            rb_funcall(handler, id_end_stream, 0);
 
505
            rb_protect(protected_end_stream, handler, &state);
304
506
            done = 1;
305
507
            break;
306
508
        }
307
509
        yaml_event_delete(&event);
 
510
        if (state) rb_jump_tag(state);
308
511
    }
309
512
 
310
513
    return self;
312
515
 
313
516
/*
314
517
 * call-seq:
315
 
 *    parser.external_encoding=(encoding)
316
 
 *
317
 
 * Set the encoding for this parser to +encoding+
318
 
 */
319
 
static VALUE set_external_encoding(VALUE self, VALUE encoding)
320
 
{
321
 
    yaml_parser_t * parser;
322
 
    VALUE exception;
323
 
 
324
 
    Data_Get_Struct(self, yaml_parser_t, parser);
325
 
 
326
 
    if(parser->encoding) {
327
 
        exception = rb_const_get_at(mPsych, rb_intern("Exception"));
328
 
        rb_raise(exception, "don't set the encoding twice!");
329
 
    }
330
 
 
331
 
    yaml_parser_set_encoding(parser, NUM2INT(encoding));
332
 
 
333
 
    return encoding;
334
 
}
335
 
 
336
 
/*
337
 
 * call-seq:
338
518
 *    parser.mark # => #<Psych::Parser::Mark>
339
519
 *
340
520
 * Returns a Psych::Parser::Mark object that contains line, column, and index
376
556
    /* UTF-16-BE Encoding with BOM */
377
557
    rb_define_const(cPsychParser, "UTF16BE", INT2NUM(YAML_UTF16BE_ENCODING));
378
558
 
 
559
    rb_require("psych/syntax_error");
379
560
    ePsychSyntaxError = rb_define_class_under(mPsych, "SyntaxError", rb_eSyntaxError);
380
561
 
381
 
    rb_define_method(cPsychParser, "parse", parse, 1);
 
562
    rb_define_method(cPsychParser, "parse", parse, -1);
382
563
    rb_define_method(cPsychParser, "mark", mark, 0);
383
 
    rb_define_method(cPsychParser, "external_encoding=", set_external_encoding, 1);
384
564
 
385
565
    id_read           = rb_intern("read");
386
566
    id_path           = rb_intern("path");