Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Postcard error: Found a varint that didn't terminate. Is the usize too big for this platform? #113

Open
PSeitz opened this issue Oct 18, 2023 · 0 comments

Comments

@PSeitz
Copy link

PSeitz commented Oct 18, 2023

As reported by a user here: quickwit-oss/quickwit#3975
Currently we don't have something to reproduce.

The error message seems to be wrong. Looking at the code this seems to occur when there's not enough bytes in the buffer (similar to UnexpectedEOF).

The docs states to support a maximum set of features of serde, but I couldn't find the list of actual supported features.

The code that probably fails is deserializing a Vec<Span>. The datastructures are simple, but there's some custom serde code which I don't know, if it's supported or not.

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Span {
    pub trace_id: TraceId,
    #[serde(with = "serde_datetime")]
    pub span_timestamp: DateTime,
}

mod serde_datetime {
    use serde::{Deserialize, Deserializer, Serializer};
    use tantivy::DateTime;

    pub(crate) fn serialize<S>(datetime: &DateTime, serializer: S) -> Result<S::Ok, S::Error>
    where S: Serializer {
        serializer.serialize_i64(datetime.into_timestamp_nanos())
    }

    pub(crate) fn deserialize<'de, D>(deserializer: D) -> Result<DateTime, D::Error>
    where D: Deserializer<'de> {
        let datetime_i64: i64 = Deserialize::deserialize(deserializer)?;
        Ok(DateTime::from_timestamp_nanos(datetime_i64))
    }
}



#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct TraceId([u8; 16]);

impl Serialize for TraceId {
    fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
        let b64trace_id = BASE64_STANDARD.encode(self.0);
        serializer.serialize_str(&b64trace_id)
    }
}

impl<'de> Deserialize<'de> for TraceId {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where D: Deserializer<'de> {
        let b64trace_id = String::deserialize(deserializer)?;

        if b64trace_id.len() != TraceId::BASE64_LENGTH {
            let message = format!(
                "base64 trace ID must be {} bytes long, got {}",
                TraceId::BASE64_LENGTH,
                b64trace_id.len()
            );
            return Err(de::Error::custom(message));
        }
        let mut trace_id = [0u8; 16];
        BASE64_STANDARD
            // Using the unchecked version here because otherwise the engine gets the wrong size
            // estimate and fails.
            .decode_slice_unchecked(b64trace_id.as_bytes(), &mut trace_id)
            .map_err(|error| {
                let message = format!("failed to decode base64 trace ID: {:?}", error);
                de::Error::custom(message)
            })?;
        Ok(TraceId(trace_id))
    }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant