Skip to content

Commit

Permalink
adding packed_broken to test suite
Browse files Browse the repository at this point in the history
  • Loading branch information
sjml committed Dec 17, 2024
1 parent 73c649d commit 2acd39f
Show file tree
Hide file tree
Showing 23 changed files with 553 additions and 53 deletions.
10 changes: 5 additions & 5 deletions beschi/writers/boilerplate/Go.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,24 +58,24 @@ func UnpackMessages(data io.Reader) ([]Message, error) {
panic(err)
}
if string(sbytes) != "BSCI" {
return nil, fmt.Errorf("Packed message buffer has invalid header.")
return nil, fmt.Errorf("packed message buffer has invalid header")
}
var msgCount int32
if err := binary.Read(data, binary.LittleEndian, &msgCount); err != nil {
return nil, fmt.Errorf("Could not read message count (%w)", err)
return nil, fmt.Errorf("could not read message count (%w)", err)
}
if msgCount == 0 {
return []Message{}, nil
}
msgList, err := ProcessRawBytes(data, int(msgCount))
if err != nil {
return nil, fmt.Errorf("Could not raw packed bytes (%w)", err)
return nil, fmt.Errorf("could not raw packed bytes (%w)", err)
}
if len(msgList) == 0 {
return nil, fmt.Errorf("No messages in buffer.")
return nil, fmt.Errorf("no messages in buffer")
}
if len(msgList) != int(msgCount) {
return nil, fmt.Errorf("Unexpected number of messages in buffer.")
return nil, fmt.Errorf("unexpected number of messages in buffer")
}
return msgList, nil;
}
2 changes: 2 additions & 0 deletions beschi/writers/boilerplate/Zig.zig
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,8 @@ pub fn unpackMessages(allocator: std.mem.Allocator, buffer: []u8) ![]Message {
return allocator.alloc(Message, 0);
}
const msg_list = try processRawBytes(allocator, buffer[offset..], @intCast(msg_count));
errdefer allocator.free(msg_list);

if (msg_list.len == 0) {
return DataReaderError.InvalidData;
}
Expand Down
18 changes: 9 additions & 9 deletions beschi/writers/go.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ def deserializer(self, var: Variable, accessor: str, by_ref: bool, declare_err:
self.write_line(f"var {var.name}_Len {self.get_native_list_size()}")
self.write_line(f"if err {':' if declare_err else ''}= binary.Read(data, binary.LittleEndian, &{var.name}_Len); err != nil {{")
self.indent_level += 1
self.write_line(f"return {'' if by_ref else 'nil, '}fmt.Errorf(\"Could not read {var.name}_Len at offset %d (%w)\", getDataOffset(data), err)")
self.write_line(f"return {'' if by_ref else 'nil, '}fmt.Errorf(\"could not read {var.name}_Len at offset %d (%w)\", getDataOffset(data), err)")
self.indent_level -= 1
self.write_line("}")
self.write_line(f"{accessor}.{var.name} = make([]{self.type_mapping[var.vartype]}, {var.name}_Len)")
Expand All @@ -72,12 +72,12 @@ def deserializer(self, var: Variable, accessor: str, by_ref: bool, declare_err:
self.write_line(f"var _{var.name} {var.vartype}")
self.write_line(f"if err {':' if declare_err else ''}= binary.Read(data, binary.LittleEndian, &_{var.name}); err != nil {{")
self.indent_level += 1
self.write_line(f"return {'' if by_ref else 'nil, '}fmt.Errorf(\"Could not read {accessor}.{var.name} at offset %d (%w)\", getDataOffset(data), err)")
self.write_line(f"return {'' if by_ref else 'nil, '}fmt.Errorf(\"could not read {accessor}.{var.name} at offset %d (%w)\", getDataOffset(data), err)")
self.indent_level -= 1
self.write_line("}")
self.write_line(f"if !isValid{var.vartype}(_{var.name}) {{")
self.indent_level += 1
self.write_line(f"return {'' if by_ref else 'nil, '}fmt.Errorf(\"Enum %d out of range for {var.vartype}\", _{var.name})")
self.write_line(f"return {'' if by_ref else 'nil, '}fmt.Errorf(\"enum %d out of range for {var.vartype}\", _{var.name})")
self.indent_level -= 1
self.write_line("}")
self.write_line(f"{accessor}.{var.name}[i{idx}] = _{var.name}")
Expand All @@ -89,26 +89,26 @@ def deserializer(self, var: Variable, accessor: str, by_ref: bool, declare_err:
elif var.vartype == "string":
self.write_line(f"if err {':' if declare_err else ''}= readString(data, &{accessor}.{var.name}); err != nil {{")
self.indent_level += 1
self.write_line(f"return {'' if by_ref else 'nil, '}fmt.Errorf(\"Could not read string at offset %d (%w)\", getDataOffset(data), err)")
self.write_line(f"return {'' if by_ref else 'nil, '}fmt.Errorf(\"could not read string at offset %d (%w)\", getDataOffset(data), err)")
self.indent_level -= 1
self.write_line("}")
elif var.vartype in self.protocol.enums:
self.write_line(f"var _{var.name} {var.vartype}")
self.write_line(f"if err {':' if declare_err else ''}= binary.Read(data, binary.LittleEndian, &_{var.name}); err != nil {{")
self.indent_level += 1
self.write_line(f"return {'' if by_ref else 'nil, '}fmt.Errorf(\"Could not read {accessor}.{var.name} at offset %d (%w)\", getDataOffset(data), err)")
self.write_line(f"return {'' if by_ref else 'nil, '}fmt.Errorf(\"could not read {accessor}.{var.name} at offset %d (%w)\", getDataOffset(data), err)")
self.indent_level -= 1
self.write_line("}")
self.write_line(f"if !isValid{var.vartype}(_{var.name}) {{")
self.indent_level += 1
self.write_line(f"return {'' if by_ref else 'nil, '}fmt.Errorf(\"Enum %d out of range for {var.vartype}\", _{var.name})")
self.write_line(f"return {'' if by_ref else 'nil, '}fmt.Errorf(\"enum %d out of range for {var.vartype}\", _{var.name})")
self.indent_level -= 1
self.write_line("}")
self.write_line(f"{accessor}.{var.name} = _{var.name}")
elif var.is_simple():
self.write_line(f"if err {':' if declare_err else ''}= binary.Read(data, binary.LittleEndian, &{accessor}.{var.name}); err != nil {{")
self.indent_level += 1
self.write_line(f"return {'' if by_ref else 'nil, '}fmt.Errorf(\"Could not read {accessor}.{var.name} at offset %d (%w)\", getDataOffset(data), err)")
self.write_line(f"return {'' if by_ref else 'nil, '}fmt.Errorf(\"could not read {accessor}.{var.name} at offset %d (%w)\", getDataOffset(data), err)")
self.indent_level -= 1
self.write_line("}")
else:
Expand Down Expand Up @@ -372,14 +372,14 @@ def generate(self) -> str:
self.write_line(f"msg, err := {msg_type}FromBytes(data)")
self.write_line("if err != nil {")
self.indent_level += 1
self.write_line(f"return nil, fmt.Errorf(\"{msg_type} read (%w)\", err)")
self.write_line(f"return nil, fmt.Errorf(\"err in {msg_type} read (%w)\", err)")
self.indent_level -= 1
self.write_line("}")
self.write_line(f"msgList = append(msgList, msg)")
self.indent_level -= 1
self.write_line("default:")
self.indent_level += 1
self.write_line(f"return nil, fmt.Errorf(\"Unknown message type: %d\", msgType)")
self.write_line(f"return nil, fmt.Errorf(\"unknown message type: %d\", msgType)")
self.indent_level -= 1
self.write_line("}")
self.indent_level -= 1
Expand Down
2 changes: 1 addition & 1 deletion docs/dev/todo.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
This file is a rough todo list for the tool itself.

## "immediate" todo
- update test suite with packed_broken (sigh)


## possible future protocol features:
- ?? inline string and array length types so they don't have to be protocol-wide like they are now
Expand Down
7 changes: 7 additions & 0 deletions test/09_packed_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,10 @@ def test_packed_message(generator_label):

def test_packed_message_writing_comparison():
test_util.check_files_identical("packed.*.msg")

def test_packed_broken_message(generator_label):
test_util.build_for(generator_label, "packed_broken", ["SmallMessages"])
test_util.run_for(generator_label, "packed_broken")

def test_packed_broken_message_writing_comparison():
test_util.check_files_identical("packed_broken.*.msg")
4 changes: 4 additions & 0 deletions test/_harnesses/assemblyscript/assembly/_harness.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
@external("env", "softAssert")
export declare function softAssert(condition: boolean, label: string): void;

// @ts-ignore: decorator
@external("env", "expectAbort")
export declare function expectAbort(errMsg: string): void;

// @ts-ignore: decorator
@external("env", "log")
export declare function log(msg: string): void;
Expand Down
37 changes: 37 additions & 0 deletions test/_harnesses/assemblyscript/assembly/packed_broken.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import * as harness from "./_harness";
export * from "./_harness";

import * as SmallMessages from '../../../../out/generated/assemblyscript/SmallMessages';


const msgList: SmallMessages.Message[] = [
new SmallMessages.IntMessage(),
new SmallMessages.FloatMessage(),
new SmallMessages.FloatMessage(),
new SmallMessages.FloatMessage(),
new SmallMessages.IntMessage(),
new SmallMessages.EmptyMessage(),
new SmallMessages.LongMessage(),
new SmallMessages.LongMessage(),
new SmallMessages.LongMessage(),
new SmallMessages.IntMessage(),
];


export function generate(): usize {
let size = SmallMessages.GetPackedSize(msgList);

harness.allocate(size);
const dv = harness.getDataView();
SmallMessages.PackMessages(msgList, dv);
dv.setUint8(4, 15);

return harness.getDataPtr();
}

export function read(): void {
const dv = harness.getDataView();

harness.expectAbort("Unexpected number of messages in buffer.");
const unpacked = SmallMessages.UnpackMessages(dv);
}
2 changes: 1 addition & 1 deletion test/_harnesses/assemblyscript/harness.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ try {
}
},
expectAbort: (message) => {
abortMessageExpectation = message;
abortMessageExpectation = liftString(message, instance.exports.memory);
},
}
});
Expand Down
105 changes: 105 additions & 0 deletions test/_harnesses/c/packed_broken.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
#include <stdlib.h>
#include <stdio.h>
#include <stddef.h>

#include "util.h"

#define SMALLMESSAGES_IMPLEMENTATION
#include "SmallMessages.h"

#ifdef _MSC_VER
// don't care about deprecations in the test harness code
#pragma warning(disable : 4996)
#endif

static void* copyDefault(const void* def, size_t size) {
if (def == NULL || size == 0) {
return NULL;
}
void* newMsg = malloc(size);
if (newMsg != NULL) {
memcpy(newMsg, def, size);
}
return newMsg;
}

int main(int argc, char** argv) {
char* genPath = NULL;
char* readPath = NULL;
parseArgs(argc, argv, &genPath, &readPath);

void** msgList = (void**)malloc(sizeof(void*) * 10);
msgList[0] = copyDefault(&SmallMessages_IntMessage_default, sizeof(SmallMessages_IntMessage_default));
msgList[1] = copyDefault(&SmallMessages_FloatMessage_default, sizeof(SmallMessages_FloatMessage_default));
msgList[2] = copyDefault(&SmallMessages_FloatMessage_default, sizeof(SmallMessages_FloatMessage_default));
msgList[3] = copyDefault(&SmallMessages_FloatMessage_default, sizeof(SmallMessages_FloatMessage_default));
msgList[4] = copyDefault(&SmallMessages_IntMessage_default, sizeof(SmallMessages_IntMessage_default));
msgList[5] = copyDefault(&SmallMessages_EmptyMessage_default, sizeof(SmallMessages_EmptyMessage_default));
msgList[6] = copyDefault(&SmallMessages_LongMessage_default, sizeof(SmallMessages_LongMessage_default));
msgList[7] = copyDefault(&SmallMessages_LongMessage_default, sizeof(SmallMessages_LongMessage_default));
msgList[8] = copyDefault(&SmallMessages_LongMessage_default, sizeof(SmallMessages_LongMessage_default));
msgList[9] = copyDefault(&SmallMessages_IntMessage_default, sizeof(SmallMessages_IntMessage_default));

size_t bufferSize;
SmallMessages_err_t err = SMALLMESSAGES_ERR_OK;
uint8_t* buffer = NULL;
FILE* fp = NULL;

if (genPath != 0) {
err = SmallMessages_GetPackedSize(msgList, 10, &bufferSize);
if (err != SMALLMESSAGES_ERR_OK) { return err; }
buffer = (uint8_t*)malloc(bufferSize);

SmallMessages_DataAccess writer = {.buffer = buffer, .bufferSize = bufferSize, .position = 0};
err = SmallMessages_PackMessages(msgList, 10, &writer);
if (err != SMALLMESSAGES_ERR_OK) { return err; }
buffer[4] = 15;

fp = fopen(genPath, "wb");
if (fp == NULL) {
fprintf(stderr, "ERROR: Couldn't open %s\n", genPath);
exit(1);
}
size_t ret = fwrite(buffer, 1, bufferSize, fp);
if (ret != bufferSize) {
fprintf(stderr, "ERROR: Couldn't write to %s\n", genPath);
exit(1);
}
fclose(fp);

free(buffer);

printf("fwrite count: %zu\nerror: %d\nbuffer size: %zu\n", ret, err, bufferSize);
printf("written to: %s\n", genPath);
}

else if (readPath != NULL) {
fp = fopen(readPath, "rb");
if (fp == NULL) {
fprintf(stderr, "ERROR: Couldn't open %s\n", readPath);
exit(1);
}
fseek(fp, 0, SEEK_END);
bufferSize = (size_t)ftell(fp);
rewind(fp);
buffer = (uint8_t*)malloc(bufferSize);
size_t ret = fread(buffer, 1, bufferSize, fp);
fclose(fp);

if (ret != bufferSize) {
fprintf(stderr, "ERROR: Couldn't read %s\n", readPath);
exit(1);
}

SmallMessages_DataAccess reader = {.buffer = buffer, .bufferSize = bufferSize, .position = 0};
void** packed = NULL;
size_t packedLen = 0;
err = SmallMessages_UnpackMessages(&reader, &packed, &packedLen);
free(buffer);

softAssert(err == SMALLMESSAGES_ERR_INVALID_DATA, "broken unpack error");
}

SmallMessages_DestroyMessageList(msgList, 10);
return check();
}
56 changes: 56 additions & 0 deletions test/_harnesses/csharp/packed_broken.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
using System;
using System.IO;
using System.Collections.Generic;


class PackedHarness: TestHarness {
static void Main(string[] args) {
var parsedArgs = parseArguments(args);

var msgList = new List<SmallMessages.Message> {
new SmallMessages.IntMessage(),
new SmallMessages.FloatMessage(),
new SmallMessages.FloatMessage(),
new SmallMessages.FloatMessage(),
new SmallMessages.IntMessage(),
new SmallMessages.EmptyMessage(),
new SmallMessages.LongMessage(),
new SmallMessages.LongMessage(),
new SmallMessages.LongMessage(),
new SmallMessages.IntMessage(),
};

if (parsedArgs.ContainsKey("generate"))
{
string outPath = parsedArgs["generate"];
string outDir = System.IO.Path.GetDirectoryName(outPath);
System.IO.Directory.CreateDirectory(outDir);
FileStream f = new FileStream(outPath, FileMode.Create);
BinaryWriter bw = new BinaryWriter(f);
SmallMessages.Message.PackMessages(msgList, bw);
bw.Flush();
bw.BaseStream.Seek(4, SeekOrigin.Begin);
bw.Write((byte)15);
bw.Flush();
}
else if (parsedArgs.ContainsKey("read"))
{
FileStream f = File.OpenRead(parsedArgs["read"]);
BinaryReader br = new BinaryReader(f);

string errMsg = "";
try
{
var unpacked = SmallMessages.Message.UnpackMessages(br);
}
catch (SmallMessages.DataReadErrorException e)
{
errMsg = e.Message;
}
softAssert(errMsg == "Unexpected number of messages in buffer.", "broken unpack error:" + errMsg);

}

check();
}
}
2 changes: 1 addition & 1 deletion test/_harnesses/go/broken/broken.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ func main() {
_, err = broken_messages.FullMessageFromBytes(dat)

softAssert(err != nil, "reading broken message")
softAssert(err.Error() == "Could not read msg.Z at offset 8 (EOF)", "broken error message")
softAssert(err.Error() == "could not read msg.Z at offset 8 (EOF)", "broken error message")
}

if !ok {
Expand Down
2 changes: 1 addition & 1 deletion test/_harnesses/go/multiple_broken/multiple_broken.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ func main() {

_, err = broken_messages.ProcessRawBytes(dat, -1)
softAssert(err != nil, "read broken stream")
softAssert(err.Error() == "Unknown message type: 63", "broken stream error message")
softAssert(err.Error() == "unknown message type: 63", "broken stream error message")
}

if !ok {
Expand Down
2 changes: 1 addition & 1 deletion test/_harnesses/go/packed/go.mod
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module multiple_broken
module packed

go 1.19

Expand Down
7 changes: 7 additions & 0 deletions test/_harnesses/go/packed_broken/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module packed_broken

go 1.19

replace messages => ../messages

require messages v0.0.0-00010101000000-000000000000
Loading

0 comments on commit 2acd39f

Please sign in to comment.