[macruby-changes] [2864] MacRuby/trunk

source_changes at macosforge.org source_changes at macosforge.org
Mon Oct 19 20:36:37 PDT 2009


Revision: 2864
          http://trac.macosforge.org/projects/ruby/changeset/2864
Author:   neeracher at apple.com
Date:     2009-10-19 20:36:35 -0700 (Mon, 19 Oct 2009)
Log Message:
-----------
Safe quoting of plain string scalars that look like non-strings

Modified Paths:
--------------
    MacRuby/trunk/ext/libyaml/rubyext.c
    MacRuby/trunk/lib/yaml/rubytypes.rb

Modified: MacRuby/trunk/ext/libyaml/rubyext.c
===================================================================
--- MacRuby/trunk/ext/libyaml/rubyext.c	2009-10-20 03:29:23 UTC (rev 2863)
+++ MacRuby/trunk/ext/libyaml/rubyext.c	2009-10-20 03:36:35 UTC (rev 2864)
@@ -359,34 +359,40 @@
     return true;
 }
 
+static char *
+detect_scalar_type(const char * val, size_t length)
+{
+  bool has_point = false;
+  if (length == 0) {
+    return "tag:yaml.org,2002:null";
+  }
+  else if (*val == ':') {
+    return "tag:ruby.yaml.org,2002:symbol";
+  }
+  else if (is_numeric(val, &has_point)) {
+    return has_point
+      ? "tag:yaml.org,2002:float"
+      : "tag:yaml.org,2002:int";
+  }
+  else if (strcmp(val, "true") == 0) {
+    return "tag:yaml.org,2002:true";
+  }
+  else if (strcmp(val, "false") == 0) {
+    return "tag:yaml.org,2002:false";
+  }
+  else {
+    return NULL;
+  }
+}
+
 static VALUE 
 handle_scalar(rb_yaml_parser_t *parser)
 {
     char *val = (char*)parser->event.data.scalar.value;
     char *tag = (char*)parser->event.data.scalar.tag;
-    bool has_point = false;
     if (parser->event.data.scalar.style == YAML_PLAIN_SCALAR_STYLE
 	&& tag == NULL) {
-	if (parser->event.data.scalar.length == 0) {
-	    tag = "tag:yaml.org,2002:null";
-	}
-	else if (*val == ':') {
-	    tag = "tag:ruby.yaml.org,2002:symbol";
-	}
-	else if (is_numeric(val, &has_point)) {
-	    tag = has_point
-		? "tag:yaml.org,2002:float"
-		: "tag:yaml.org,2002:int";
-	}
-	else if (strcmp(val, "true") == 0) {
-	    tag = "tag:yaml.org,2002:true";
-	}
-	else if (strcmp(val, "false") == 0) {
-	    tag = "tag:yaml.org,2002:false";
-	}
-	else {
-	    tag = "tag:yaml.org,2002:str";
-	}
+      tag = detect_scalar_type(val, parser->event.data.scalar.length);
     }
     if (tag == NULL) {
 	tag = "tag:yaml.org,2002:str";
@@ -555,17 +561,21 @@
 }
 
 static yaml_char_t*
-rb_yaml_tag_or_null(VALUE tagstr, int *can_omit_tag)
+rb_yaml_tag_or_null(VALUE tagstr, int *can_omit_tag, int * string_tag)
 {
     // TODO make this part of the resolver chain; this is the wrong place for it
     const char *tag = RSTRING_PTR(tagstr);
-    if ((strcmp(tag, "tag:yaml.org,2002:int") == 0) ||
+    if (strcmp(tag, "tag:yaml.org,2002:str") == 0) {
+	*can_omit_tag = 1;
+	*string_tag   = 1;
+	return NULL;	
+    }
+    else if ((strcmp(tag, "tag:yaml.org,2002:int") == 0) ||
 	    (strcmp(tag, "tag:yaml.org,2002:float") == 0) ||
 	    (strcmp(tag, "tag:ruby.yaml.org,2002:symbol") == 0) ||
 	    (strcmp(tag, "tag:yaml.org,2002:true") == 0) ||
 	    (strcmp(tag, "tag:yaml.org,2002:false") == 0) ||
 	    (strcmp(tag, "tag:yaml.org,2002:null") == 0) ||
-	    (strcmp(tag, "tag:yaml.org,2002:str") == 0) ||
 	    (strcmp(tag, YAML_DEFAULT_SEQUENCE_TAG) == 0) ||
 	    (strcmp(tag, YAML_DEFAULT_MAPPING_TAG) == 0)) {
 	*can_omit_tag = 1;
@@ -688,7 +698,8 @@
     yaml_emitter_t *emitter = &RYAMLEmitter(self)->emitter;
 
     int can_omit_tag = 0;
-    yaml_char_t *tag = rb_yaml_tag_or_null(taguri, &can_omit_tag);
+    int string_tag   = 0;
+    yaml_char_t *tag = rb_yaml_tag_or_null(taguri, &can_omit_tag, &string_tag);
     yaml_sequence_start_event_initialize(&ev, NULL, tag, can_omit_tag,
 	    rb_symbol_to_sequence_style(style));
     yaml_emitter_emit(emitter, &ev);
@@ -707,7 +718,8 @@
     yaml_emitter_t *emitter = &RYAMLEmitter(self)->emitter;
 
     int can_omit_tag = 0;
-    yaml_char_t *tag = rb_yaml_tag_or_null(taguri, &can_omit_tag);
+    int string_tag   = 0;
+    yaml_char_t *tag = rb_yaml_tag_or_null(taguri, &can_omit_tag, &string_tag);
     yaml_mapping_start_event_initialize(&ev, NULL, tag, can_omit_tag,
 	    rb_symbol_to_mapping_style(style));
     yaml_emitter_emit(emitter, &ev);
@@ -726,11 +738,21 @@
     yaml_event_t ev;
     yaml_emitter_t *emitter = &RYAMLEmitter(self)->emitter;
     yaml_char_t *output = (yaml_char_t *)RSTRING_PTR(val);
+    size_t length = strlen((const char *)output);
 
     int can_omit_tag = 0;
-    yaml_char_t *tag = rb_yaml_tag_or_null(taguri, &can_omit_tag);
-    yaml_scalar_event_initialize(&ev, NULL, tag, output, strlen((const char *)output),
-	    can_omit_tag, can_omit_tag, rb_symbol_to_scalar_style(style));
+    int string_tag   = 0;
+    yaml_char_t *tag = rb_yaml_tag_or_null(taguri, &can_omit_tag, &string_tag);
+    yaml_scalar_style_t sstyl = rb_symbol_to_scalar_style(style);
+    if (string_tag && 
+	(sstyl==YAML_ANY_SCALAR_STYLE || sstyl==YAML_PLAIN_SCALAR_STYLE) &&
+	(detect_scalar_type((const char *)output, length) != NULL)
+    ) {
+      /* Quote so this is read back as a string, no matter what type it looks like */
+      sstyl = YAML_DOUBLE_QUOTED_SCALAR_STYLE;
+    }
+    yaml_scalar_event_initialize(&ev, NULL, tag, output, length,
+	    can_omit_tag, can_omit_tag, sstyl);
     yaml_emitter_emit(emitter, &ev);
 
     return self;

Modified: MacRuby/trunk/lib/yaml/rubytypes.rb
===================================================================
--- MacRuby/trunk/lib/yaml/rubytypes.rb	2009-10-20 03:29:23 UTC (rev 2863)
+++ MacRuby/trunk/lib/yaml/rubytypes.rb	2009-10-20 03:36:35 UTC (rev 2864)
@@ -63,7 +63,7 @@
   
   def to_yaml(output = nil)
     YAML::quick_emit(output) do |out|
-      out.scalar(taguri, self, self =~ /^:/ ? :quote2 : nil)
+      out.scalar(taguri, self, to_yaml_style)
     end
   end
 
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/macruby-changes/attachments/20091019/bf3faaf7/attachment-0001.html>


More information about the macruby-changes mailing list