CVE-2012-0037

Enforce entity loading policy in raptor_libxml_resolveEntity
and raptor_libxml_getEntity by checking for file URIs and network URIs.

Add RAPTOR_OPTION_LOAD_EXTERNAL_ENTITIES / loadExternalEntities for
turning on loading of XML external entity loading, disabled by default.

This affects all the parsers that use SAX2: rdfxml, rss-tag-soup (and
aliases) and rdfa.
raptor_rss_emit(raptor_parser* rdf_parser)
{
  raptor_rss_parser* rss_parser = (raptor_rss_parser*)rdf_parser->context;
  int i;
  raptor_rss_item* item;
  int rc = 0;

  if(!rss_parser->model.common[RAPTOR_RSS_CHANNEL]) {
    raptor_parser_error(rdf_parser, "No RSS channel item present");
    return 1;
  }
  
  if(!rss_parser->model.common[RAPTOR_RSS_CHANNEL]->term) {
    raptor_parser_error(rdf_parser, "RSS channel has no identifier");
    return 1;
  }

  /* Emit start default graph mark */
  raptor_parser_start_graph(rdf_parser, NULL, 0);
  rdf_parser->emitted_default_graph++;


  /* Emit all the common type blocks (channel, author, ...) */
  for(i = 0; i< RAPTOR_RSS_COMMON_SIZE; i++) {
    for(item = rss_parser->model.common[i]; item; item = item->next) {
      if(!item->fields_count)
        continue;
      
      RAPTOR_DEBUG3("Emitting type %i - %s\n", i, raptor_rss_items_info[i].name);
      
      if(!item->term) {
        raptor_parser_error(rdf_parser, "RSS %s has no identifier",
                            raptor_rss_items_info[i].name);
        rc = 1;
        goto tidy;
      }
    
      if(raptor_rss_emit_item(rdf_parser, item)) {
        rc = 1;
        goto tidy;
      }

      /* Add connections to channel */
      if(i != RAPTOR_RSS_CHANNEL) {
        if(raptor_rss_emit_connection(rdf_parser,
                                      rss_parser->model.common[RAPTOR_RSS_CHANNEL]->term,
                                      rdf_parser->world->rss_types_info_uris[i], 0,
                                      item->term)) {
          rc = 1;
          goto tidy;
        }
      }
    }
  }


  /* Emit the feed item blocks */
  if(rss_parser->model.items_count) {
    const unsigned char* id;
    raptor_term *items;

    id = raptor_world_generate_bnodeid(rdf_parser->world);
    
    /* make a new genid for the <rdf:Seq> node */
    items = raptor_new_term_from_blank(rdf_parser->world, id);
    RAPTOR_FREE(char*, id);

    /* _:genid1 rdf:type rdf:Seq . */
    if(raptor_rss_emit_type_triple(rdf_parser, items,
                                   RAPTOR_RDF_Seq_URI(rdf_parser->world))) {
      raptor_free_term(items);
      rc = 1;
      goto tidy;
    }
    
    /* <channelURI> rss:items _:genid1 . */
    if(raptor_rss_emit_connection(rdf_parser,
                                  rss_parser->model.common[RAPTOR_RSS_CHANNEL]->term,
                                  rdf_parser->world->rss_fields_info_uris[RAPTOR_RSS_FIELD_ITEMS], 0,
                                  items)) {
      raptor_free_term(items);
      rc= 1;
      goto tidy;
    }
    
    /* sequence of rss:item */
    for(i = 1, item = rss_parser->model.items; item; item = item->next, i++) {
      
      if(raptor_rss_emit_item(rdf_parser, item) ||
         raptor_rss_emit_connection(rdf_parser, items, NULL, i,item->term)) {
        raptor_free_term(items);
        rc = 1;
        goto tidy;
      }
    }

    raptor_free_term(items);
  }

  tidy:
  if(rdf_parser->emitted_default_graph) {
    raptor_parser_end_graph(rdf_parser, NULL, 0);
    rdf_parser->emitted_default_graph--;
  }

  return rc;
}

raptor_rss_emit(raptor_parser* rdf_parser)
{
  raptor_rss_parser* rss_parser = (raptor_rss_parser*)rdf_parser->context;
  int i;
  raptor_rss_item* item;
  int rc = 0;

  if(!rss_parser->model.common[RAPTOR_RSS_CHANNEL]) {
    raptor_parser_error(rdf_parser, "No RSS channel item present");
    return 1;
  }
  
  if(!rss_parser->model.common[RAPTOR_RSS_CHANNEL]->term) {
    raptor_parser_error(rdf_parser, "RSS channel has no identifier");
    return 1;
  }

  /* Emit start default graph mark */
  raptor_parser_start_graph(rdf_parser, NULL, 0);
  rdf_parser->emitted_default_graph++;


  /* Emit all the common type blocks (channel, author, ...) */
  for(i = 0; i< RAPTOR_RSS_COMMON_SIZE; i++) {
    for(item = rss_parser->model.common[i]; item; item = item->next) {
      if(!item->fields_count)
        continue;
      
      RAPTOR_DEBUG3("Emitting type %i - %s\n", i, raptor_rss_items_info[i].name);
      
      if(!item->term) {
        raptor_parser_error(rdf_parser, "RSS %s has no identifier",
                            raptor_rss_items_info[i].name);
        rc = 1;
        goto tidy;
      }
    
      if(raptor_rss_emit_item(rdf_parser, item)) {
        rc = 1;
        goto tidy;
      }

      /* Add connections to channel */
      if(i != RAPTOR_RSS_CHANNEL) {
        if(raptor_rss_emit_connection(rdf_parser,
                                      rss_parser->model.common[RAPTOR_RSS_CHANNEL]->term,
                                      rdf_parser->world->rss_types_info_uris[i], 0,
                                      item->term)) {
          rc = 1;
          goto tidy;
        }
      }
    }
  }


  /* Emit the feed item blocks */
  if(rss_parser->model.items_count) {
    const unsigned char* id;
    raptor_term *items;

    id = raptor_world_generate_bnodeid(rdf_parser->world);
    
    /* make a new genid for the <rdf:Seq> node */
    items = raptor_new_term_from_blank(rdf_parser->world, id);
    RAPTOR_FREE(char*, id);

    /* _:genid1 rdf:type rdf:Seq . */
    if(raptor_rss_emit_type_triple(rdf_parser, items,
                                   RAPTOR_RDF_Seq_URI(rdf_parser->world))) {
      raptor_free_term(items);
      rc = 1;
      goto tidy;
    }
    
    /* <channelURI> rss:items _:genid1 . */
    if(raptor_rss_emit_connection(rdf_parser,
                                  rss_parser->model.common[RAPTOR_RSS_CHANNEL]->term,
                                  rdf_parser->world->rss_fields_info_uris[RAPTOR_RSS_FIELD_ITEMS], 0,
                                  items)) {
      raptor_free_term(items);
      rc= 1;
      goto tidy;
    }
    
    /* sequence of rss:item */
    for(i = 1, item = rss_parser->model.items; item; item = item->next, i++) {
      
      if(raptor_rss_emit_item(rdf_parser, item) ||
         raptor_rss_emit_connection(rdf_parser, items, NULL, i,item->term)) {
        raptor_free_term(items);
        rc = 1;
        goto tidy;
      }
    }

    raptor_free_term(items);
  }

  tidy:
  if(rdf_parser->emitted_default_graph) {
    raptor_parser_end_graph(rdf_parser, NULL, 0);
    rdf_parser->emitted_default_graph--;
  }

  return rc;
}
