FIX: handle empty tag

This commit is contained in:
Mike Dilger 2024-04-25 10:35:32 +12:00
parent f6156593bd
commit 9b0f293230
2 changed files with 61 additions and 4 deletions

View File

@ -118,7 +118,6 @@ pub fn read_kind(input: &[u8], inposp: &mut usize) -> Result<u16, Error> {
}
}
// HELP written for event only
// From the outer bracket through to the character after the close outer bracket
// returns the size of data written to the output
pub fn read_tags_array(
@ -234,10 +233,19 @@ pub fn read_tag(
output: &mut [u8],
outposp: &mut usize,
) -> Result<(), Error> {
verify_char(input, b'"', inposp)?;
let countpos = *outposp;
*outposp += 2;
// handle empty tag
if input[*inposp] == b']' {
*inposp += 1;
put(output, countpos, 0_u16.to_ne_bytes().as_slice())?;
return Ok(());
}
verify_char(input, b'"', inposp)?;
let mut num_strings: usize = 1;
loop {
// read string
@ -336,7 +344,11 @@ pub fn burn_string(input: &[u8], inposp: &mut usize) -> Result<(), Error> {
// ending on the character following the close brace
pub fn burn_tag(input: &[u8], inposp: &mut usize) -> Result<(), Error> {
eat_whitespace(input, inposp);
// assuming that every tag must have at least one string
// handle empty tag
if input[*inposp] == b']' {
*inposp += 1;
return Ok(());
}
verify_char(input, b'"', inposp)?;
burn_string(input, inposp)?;
eat_whitespace(input, inposp);

View File

@ -1,4 +1,5 @@
use crate::error::{ChorusError, Error};
use crate::types::parse::json_parse::read_tags_array;
use std::fmt;
/*
@ -32,6 +33,15 @@ impl<'a> Tags<'a> {
Ok(Tags(&input[0..len]))
}
/// Parse JSON input into a Tags.
///
/// Returns the count of consumed input bytes and the Tags
pub fn from_json(json: &[u8], output_buffer: &'a mut [u8]) -> Result<(usize, Tags<'a>), Error> {
let mut inpos: usize = 0;
let tags_size = read_tags_array(json, &mut inpos, output_buffer)?;
Ok((inpos, Tags(&output_buffer[..tags_size])))
}
// This copies
pub fn copy(&self, output: &mut [u8]) -> Result<(), Error> {
if output.len() < self.0.len() {
@ -284,4 +294,39 @@ mod test {
r#"[["Hello world!","Hello","world!"],["p","ee11a5dff40c19a555f41fe42b48f00e618c91225622ae37b6c2bb67b76c4e49"]]"#
);
}
#[test]
fn test_tags_from_json() {
let mut output: Vec<u8> = Vec::with_capacity(4096);
output.resize(4096, 0);
let json = r#"[["Hello world!","Hello","world!"],["p","ee11a5dff40c19a555f41fe42b48f00e618c91225622ae37b6c2bb67b76c4e49"]]"#;
let (_, tags) = Tags::from_json(json.as_bytes(), &mut output).unwrap();
assert_eq!(tags.get_string(0, 0), Some(b"Hello world!".as_slice()));
assert_eq!(tags.get_string(0, 1), Some(b"Hello".as_slice()));
assert_eq!(tags.get_string(0, 2), Some(b"world!".as_slice()));
assert_eq!(tags.get_string(0, 3), None);
assert_eq!(tags.get_string(1, 0), Some(b"p".as_slice()));
assert_eq!(
tags.get_string(1, 1),
Some(b"ee11a5dff40c19a555f41fe42b48f00e618c91225622ae37b6c2bb67b76c4e49".as_slice())
);
assert_eq!(tags.get_string(1, 2), None);
assert_eq!(tags.get_string(2, 0), None);
}
#[test]
fn test_empty_tag() {
let mut output: Vec<u8> = Vec::with_capacity(256);
output.resize(256, 0);
let json = r#"[[]]"#;
let (_, _tags) = Tags::from_json(json.as_bytes(), &mut output).unwrap();
let json = r#"[["-"],[]]"#;
let (_, tags) = Tags::from_json(json.as_bytes(), &mut output).unwrap();
assert_eq!(tags.get_string(0, 0), Some(b"-".as_slice()));
}
}