[ 
https://issues.apache.org/jira/browse/AVRO-3810?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17833390#comment-17833390
 ] 

Thiruvalluvan M. G. commented on AVRO-3810:
-------------------------------------------

Good catch. The problem a bit more generic. While processing implicit actions, 
indirect symbols and symbolic links are not handled causing incomplete 
processing. The fix is to unwind indirect symbols and navigating through the 
symbolic links. This is done in the pull request: 
https://github.com/apache/avro/pull/2833

> Incorrect JSON generated by avro::jsonEncoder from avro::GenericDatum when 
> schema contains as last value a record with 0 field
> ------------------------------------------------------------------------------------------------------------------------------
>
>                 Key: AVRO-3810
>                 URL: https://issues.apache.org/jira/browse/AVRO-3810
>             Project: Apache Avro
>          Issue Type: Bug
>          Components: c++
>         Environment: Windows, 64bit, compiled with msvc
>            Reporter: Jerome Delrieu
>            Assignee: Thiruvalluvan M. G.
>            Priority: Major
>
> When the Schema has a record with 0 field as its last value, the 
> avro::jsonEncoder doesn't generate the last characters in the JSON string.
> The obtained JSON string is malformed and cannot be parsed with a standard 
> JSON parser.
> Note : the avro::{color:#74531f}jsonDecoder {color}accept this string whereas 
> it is not a valid JSON syntax
> small C++ example:
> {color:#0000FF}const{color} {color:#0000FF}char{color} 
> *{color:#1f377f}sSchema{color} = 
> {color:#e21f1f}"{color}{color:#a31515}{{color}{color:#b776fb}\"{color}{color:#a31515}type{color}{color:#b776fb}\"{color}{color:#a31515}:
>  
> {color}{color:#b776fb}\"{color}{color:#a31515}record{color}{color:#b776fb}\"{color}{color:#a31515},{color}{color:#b776fb}\"{color}{color:#a31515}name{color}{color:#b776fb}\"{color}{color:#a31515}
>  : 
> {color}{color:#b776fb}\"{color}{color:#a31515}Event{color}{color:#b776fb}\"{color}{color:#a31515},{color}{color:#b776fb}\"{color}{color:#a31515}namespace{color}{color:#b776fb}\"{color}{color:#a31515}
>  : 
> {color}{color:#b776fb}\"{color}{color:#a31515}test{color}{color:#b776fb}\"{color}{color:#a31515},{color}{color:#b776fb}\"{color}{color:#a31515}doc{color}{color:#b776fb}\"{color}{color:#a31515}
>  : {color}{color:#b776fb}\"\"{color}{color:#a31515}, 
> {color}{color:#b776fb}\"{color}{color:#a31515}fields{color}{color:#b776fb}\"{color}{color:#a31515}
>  : {color}{color:#e21f1f}"{color}   {color:#e21f1f}"{color}{color:#a31515}[ { 
> {color}{color:#b776fb}\"{color}{color:#a31515}name{color}{color:#b776fb}\"{color}{color:#a31515}:
>  
> {color}{color:#b776fb}\"{color}{color:#a31515}Event{color}{color:#b776fb}\"{color}{color:#a31515},
>  
> {color}{color:#b776fb}\"{color}{color:#a31515}type{color}{color:#b776fb}\"{color}{color:#a31515}
>  : [ {  
> {color}{color:#b776fb}\"{color}{color:#a31515}type{color}{color:#b776fb}\"{color}{color:#a31515}:
>  
> {color}{color:#b776fb}\"{color}{color:#a31515}record{color}{color:#b776fb}\"{color}{color:#a31515},
>   
> {color}{color:#b776fb}\"{color}{color:#a31515}name{color}{color:#b776fb}\"{color}{color:#a31515}
>  : 
> {color}{color:#b776fb}\"{color}{color:#a31515}ABEvent{color}{color:#b776fb}\"{color}{color:#a31515},
>  
> {color}{color:#b776fb}\"{color}{color:#a31515}doc{color}{color:#b776fb}\"{color}{color:#a31515}
>  : 
> {color}{color:#b776fb}\"{color}{color:#a31515}unused{color}{color:#b776fb}\"{color}{color:#a31515},{color}{color:#e21f1f}"{color}
>    
> {color:#e21f1f}"{color}{color:#b776fb}\"{color}{color:#a31515}fields{color}{color:#b776fb}\"{color}{color:#a31515}
>  : [ ] } ] } ] }{color}{color:#e21f1f}"{color};
> avro::{color:#2b91af}ValidSchema{color} 
> {color:#1f377f}schema{color}(avro::{color:#74531f}compileJsonSchemaFromString{color}({color:#1f377f}sSchema{color}));
>  avro::{color:#2b91af}GenericDatum{color} 
> {color:#1f377f}datumDecode{color}({color:#1f377f}schema{color}); 
> avro::{color:#2b91af}DecoderPtr{color} {color:#1f377f}decoder{color} = 
> avro::{color:#74531f}binaryDecoder{color}();
> {color:#008000}// only one byte, 0, as source for decoding{color} 
> {color:#2b91af}uint8_t{color} {color:#1f377f}binarySource{color} = 0; 
> std::{color:#2b91af}unique_ptr{color}<avro::{color:#2b91af}InputStream{color}>
>  {color:#1f377f}in{color} = 
> avro::{color:#74531f}memoryInputStream{color}(({color:#2b91af}uint8_t{color} 
> *)&{color:#1f377f}binarySource{color}, 1); 
> {color:#1f377f}decoder{color}{color:#008080}->{color}{color:#74531f}init{color}({color:#008080}*{color}{color:#1f377f}in{color});
>  
> avro::{color:#74531f}decode{color}({color:#008080}*{color}{color:#1f377f}decoder{color},
>  {color:#1f377f}datumDecode{color});
> std::{color:#2b91af}unique_ptr{color}<avro::{color:#2b91af}OutputStream{color}>
>  {color:#1f377f}out{color} = avro::{color:#74531f}memoryOutputStream{color}();
> std::{color:#2b91af}shared_ptr{color}<avro::{color:#2b91af}Encoder{color}> 
> {color:#1f377f}encoder{color} = 
> avro::{color:#74531f}jsonEncoder{color}({color:#1f377f}schema{color});
> {color:#1f377f}encoder{color}{color:#008080}->{color}{color:#74531f}init{color}({color:#008080}*{color}{color:#1f377f}out{color});
>  
> avro::{color:#74531f}encode{color}({color:#008080}*{color}{color:#1f377f}encoder{color},
>  {color:#1f377f}datumDecode{color}); 
> {color:#1f377f}encoder{color}{color:#008080}->{color}{color:#74531f}flush{color}();
> {color:#0000FF}const{color} 
> std::{color:#2b91af}shared_ptr{color}<std::{color:#2b91af}vector{color}<{color:#2b91af}uint8_t{color}>
>  > &{color:#1f377f}buffer{color} = 
> avro::{color:#74531f}snapshot{color}(*{color:#1f377f}out{color}.{color:#74531f}get{color}());
> std::{color:#2b91af}string{color} 
> {color:#1f377f}result{color}({color:#0000FF}reinterpret_cast{color}<{color:#0000FF}char{color}
>  
> *>({color:#1f377f}buffer{color}.{color:#74531f}get{color}()->{color:#74531f}data{color}()),
>  
> {color:#1f377f}buffer{color}.{color:#74531f}get{color}()->{color:#74531f}size{color}());
>  
> Example Schema:
> Schema:
> {
>   "type": "record",
>   "name": "Event",
>   "namespace": "test",
>   "doc": "",
>   "fields": [
>     {
>       "name": "Event",
>       "type": [
>         {
>           "type": "record",
>           "name": "ABEvent",
>           "doc": "unused",
>           "fields": [
>             
>           ]
>         }
>       ]
>     }
>   ]
> }
>  
> Binary source : 1 byte 00
> Result:
> {"Event":{"test.ABEvent":
>  
>  
> A small patch to lang\c++\impl\parsing\Symbol.hh can solve this issue
> Before:
>     void processImplicitActions() {
>         for (;;) {
>             Symbol &s = parsingStack.top();
>             if (s.isImplicitAction()) {
>                 handler_.handle(s);
>                 parsingStack.pop();
>             } else if (s.kind() == Symbol::Kind::SkipStart) {
>                 parsingStack.pop();
>                 skip(*decoder_);
>             } else {
>                 break;
>             }
>         }
>     }
> After:
>     void processImplicitActions() {
>         for (;;) {
>             Symbol &s = parsingStack.top();
>             if (s.isImplicitAction()) {
>                 handler_.handle(s);
>                 parsingStack.pop();
>             } else if (s.kind() == Symbol::Kind::SkipStart) {
>                 parsingStack.pop();
>                 skip(*decoder_);
>             } else if (s.kind() == Symbol::Kind::Indirect) {
>                 parsingStack.pop();
>                 parsingStack.push(Symbol::recordEndSymbol());
>                 parsingStack.push(Symbol::recordStartSymbol());
>             } else {
>                 break;
>             }
>         }
>     }
>  
>  
>  



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to