Skip to content

write_str_simd_fastest can accidentally write strings twice. under miri #62

@EmilyMatt

Description

@EmilyMatt

In write_str_simd_fastest, When avx2 and sse4.2 do not exist
we fall to

#[cfg(not(feature = "portable"))]
return write_string_rust(writer, string);
#[cfg(feature = "portable")]
return write_str_simd_portable(writer, string);

write_str_simd_portable ends with

*string = string.get_unchecked(idx..);
Ok(())

However write_string_rust simply does

writer.write_all(string)

The issue arises in write_string_content, which does this:

#[inline]
    fn write_string_content(&mut self, string: &str) -> io::Result<()> {
        let mut string = string.as_bytes();
        unsafe {
            // Looking at the table above the lower 5 bits are entirely
            // quote characters that gives us a bitmask of 0x1f for that
            // region, only quote (`"`) and backslash (`\`) are not in
            // this range.
            stry!(self.write_str_simd(&mut string));
        }
        write_string_rust(self.get_writer(), &mut string)
    }

So in the case where not(feature = "portable"), we write the string, we don't advance it, and then we call write_string_rust again on the not advanced string, unlike the other cases.
This is a weird edge case caused by miri messing with the target detection, I think.
The underlying issue still exists, when compiling with runtime_detection, no portable, and the x86_64 CPU does not have avx or the other feature

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions