Skip to content

Commit

Permalink
Add string length validation, add full UUID support, add test
Browse files Browse the repository at this point in the history
  • Loading branch information
Yu-Vitaqua-fer-Chronos committed Dec 3, 2023
1 parent fbfa897 commit 923c289
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 10 deletions.
5 changes: 3 additions & 2 deletions modernnet.nimble
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Package

version = "2.0.1"
version = "2.1.0"
author = "Yu-Vitaqua-fer-Chronos"
description = "ModernNet implements a packet reading and writing system, as well as some useful tools for implementing this into your own project!"
license = "Apache-2.0"
Expand All @@ -11,4 +11,5 @@ srcDir = "src"

requires "nim >= 2.0.0" # May work on earlier versions, only tested on latest stable versions
requires "zippy >= 0.10.9" # Used for handling compressed MC packets
requires "regex >= 0.23.0" # Pure Nim regex engine, used for verifying identifiers
requires "regex >= 0.23.0" # Pure Nim regex engine, used for verifying identifiers
requires "https://github.com/Yu-Vitaqua-fer-Chronos/uuids >= 0.1.12" # Used for handling UUIDs
19 changes: 18 additions & 1 deletion src/modernnet/buffer.nim
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,13 @@ func writeVarNum*[R: int32 | int64](b: Buffer, value: R) =
b.writeNum(cast[uint8]((val and SegmentBits) or ContinueBit))
val = val shr 7

func writeUUID*(b: Buffer, uuid: UUID) =
## Writes a UUID to a buffer
b.writeNum[:int64](uuid.mostSigBits())
b.writeNum[:int64](uuid.leastSigBits())

func writeString*(b: Buffer, s: string) =
## Writes a string to a buffer
b.writeVarNum[:int32](s.len.int32)
if (b.pos + s.len) > b.buf.len:
b.buf.setLen(b.pos + s.len)
Expand Down Expand Up @@ -109,14 +115,25 @@ func readVarNum*[R: int32 | int64](b: Buffer): R {.raises: [MnEndOfBufferError,
else:
{.error: "Deserialisation of `" & $R & "` is not implemented!".}

func readString*(b: Buffer): string {.raises: [MnEndOfBufferError, MnPacketParsingError].} =
func readUUID*(b: Buffer): UUID =
## Reads a UUID from a buffer
initUUID(b.readNum[:int64](), b.readNum[:int64]())

func readString*(b: Buffer, maxLength = 32767): string {.raises: [MnEndOfBufferError, MnPacketParsingError].} =
## Reads a string from a buffer
let length = b.readVarNum[:int32]()

if length > maxLength * 3:
raise newException(MnStringTooLongParsingError, "String is too long!")

result.setLen(length)

let data = b.buf[b.pos..<(b.pos+length)]
result = cast[string](data)

if result.len > maxLength:
raise newException(MnStringTooLongParsingError, "String is too long!")

b.pos += length

template readIdentifier*(b: Buffer): Identifier =
Expand Down
2 changes: 2 additions & 0 deletions src/modernnet/exceptions.nim
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,6 @@ type

MnInvalidPositionConstructionError* = object of MnPacketConstructionError

MnStringTooLongParsingError* = object of MnPacketParsingError

MnConnectionClosedError* = object of MnError
2 changes: 1 addition & 1 deletion src/modernnet/helpers.nim
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func buildServerListJson*(versionName: string, versionProtocol,
import modernnet

let sample = @[PlayerSample(name: "VeryRealPlayer",
id: "7f81c9a5-4aae-4ace-abd2-1586392441de".UUID)]
id: "7f81c9a5-4aae-4ace-abd2-1586392441de".parseUUID())]

let serverList = buildServerListJson("1.19.4", 762, 100,
sample.len, sample, "Much wow")
Expand Down
18 changes: 13 additions & 5 deletions src/modernnet/types.nim
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,12 @@
import std/[
strformat, # Used for pretty error printing
strutils, # Used for basic text manipulation (`split` for idents)
json, # JSON hooks for UUIDs
re # Use this to validate identifiers via regex
]

import regex
import uuids

import "."/[
exceptions # Imported so we can raise specific errors
Expand All @@ -29,8 +31,6 @@ const
IdentifierValueRegex = re2"[a-z0-9.-_/]"

type
UUID* = distinct string ## A distinct string for UUIDs.

Identifier* = object
## An MC identifier.
namespace*, value*: string
Expand All @@ -43,8 +43,6 @@ type
pos: int64
format: PositionFormat

func `$`*(uuid: UUID): string = uuid.string

proc `$`*(i: Identifier): string =
## Get an identifier as a string.
return i.namespace & ":" & i.value
Expand Down Expand Up @@ -116,4 +114,14 @@ proc fromPos*(pos: Position, format = XZY): int64 =
return ((pos.x.int64 and 0x3FFFFFF) shl 38) or ((pos.y.int64 and 0xFFF) shl 26) or (pos.z.int64 and 0x3FFFFFF)

else:
raise newException(MnInvalidPositionConstructionError, "How did you *get* here?")
raise newException(MnInvalidPositionConstructionError, "How did you *get* here?")

func fromJsonHook*(uuid: var UUID, node: JsonNode) =
## Converts a UUID from JSON.
uuid = node.getStr().parseUUID()

func toJsonHook*(uuid: UUID): JsonNode =
## Converts a UUID to JSON.
newJString($uuid)

export UUID, parseUUID, uuids.`$`, mostSigBits, leastSigBits, initUUID
13 changes: 12 additions & 1 deletion tests/test1.nim
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,18 @@ test "VarNum tests":
assert buffer.readVarNum[:int64]() == c, "VarLong test 1 failed!"
assert buffer.readVarNum[:int64]() == d, "VarLong test 2 failed!"

test "String parsing":
test "UUID parsing/serialising":
var buffer = newBuffer()

var a = parseUUID("7f81c9a5-4aae-4ace-abd2-1586392441de")

buffer.writeUUID(a)

buffer.pos = 0

assert buffer.readUUID() == a, "UUID test failed!"

test "String parsing/serialising":
var buffer = newBuffer()

var a = "Hello world!"
Expand Down

0 comments on commit 923c289

Please sign in to comment.