Skip to content

readFile implementation in Prelude.File partially broken with binary files #4352

@ghost

Description

The current implementation uses addToStringBuffer to concatenate a read file chunk to a buffer.
Explicit length parameters seem to be used almost everywhere(?), however not for addToStringBuffer,
which uses C strlen in the underlying implementation to deduce the length of the concatenee.
strlen uses C style strings, resulting in truncation of the read chunk at null characters.

Proposal: require an explicit length parameter for idris_addToString

addToStringBuffer contents l

addToStringBuffer (MkString ptr) str =
foreign FFI_C "idris_addToString" (Ptr -> String -> IO ())
ptr str

| Just (FFun "idris_addToString" [(_, strBuf), (_, str)] _) <- foreignFromTT arity ty fn xs
= case (strBuf, str) of
(EStringBuf ref, EConstant (Str add)) ->
do execIO $ modifyIORef ref (++add)
execApp env ctxt ioUnit (drop arity xs)
_ -> execFail . Msg $
"The arguments to idris_addToString should be a StringBuffer and a String, but were " ++
show strBuf ++ " and " ++ show str ++
". Are all cases covered?"

void idris_addToString(void* buffer, char* str);

void idris_addToString(void* buffer, char* str) {
StrBuffer* sb = (StrBuffer*)buffer;
int len = strlen(str);
memcpy(sb->string + sb->len, str, len+1);
sb->len += len;
}

A more grand proposal?: Should Idris globally switch to netstring style strings instead of C strings? I don't know how pervasive things like this are.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions