1/*
2 * LegacyClonk
3 *
4 * Copyright (c) RedWolf Design
5 * Copyright (c) 2007, Sven2
6 * Copyright (c) 2017-2020, The LegacyClonk Team and contributors
7 *
8 * Distributed under the terms of the ISC license; see accompanying file
9 * "COPYING" for details.
10 *
11 * "Clonk" is a registered trademark of Matthes Bender, used with permission.
12 * See accompanying file "TRADEMARK" for details.
13 *
14 * To redistribute this file separately, substitute the full license texts
15 * for the above references.
16 */
17
18// user input validation functions
19
20#pragma once
21
22#include "C4Constants.h"
23#include "StdAdaptors.h"
24#include "StdBuf.h"
25#include "StdFile.h"
26
27namespace C4InVal
28{
29 // validation options
30 enum ValidationOption
31 {
32 VAL_Filename, // regular filenames only (Sven2.c4p)
33 VAL_SubPathFilename, // filenames and optional subpath (Spieler\Sven2.c4p)
34 VAL_FullPath, // full filename paths (C:\Clonk\Sven2.c4p; ..\..\..\..\AutoExec.bat)
35#ifdef C4ENGINE
36 VAL_NameAllowEmpty, // stuff like player names (Sven2). No markup. Max. C4MaxName characters. Spaces trimmed.
37 VAL_NameNoEmpty, // same as above, but empty string not allowed
38 VAL_NameExAllowEmpty, // stuff like Clonk names (Joki the {{WIPF}}). Markup allowed. Max. C4MaxLongName characters. Spaces trimmed.
39 VAL_NameExNoEmpty, // same as above, but empty string not allowed
40 VAL_IRCName, // nickname for IRC. a-z, A-Z, _^{[]} only; 0-9|- inbetween
41 VAL_IRCPass, // password for IRC
42 VAL_IRCChannel, // IRC channel name
43 VAL_Comment, // comment - just a length limit
44#endif
45 };
46
47 // input validation functions: Validate input by changing it to an allowed value if possible
48 // issues warnings in log and returns true if such an action is performed
49 bool ValidateString(char *szString, ValidationOption eOption, size_t iMaxSize);
50 bool ValidateString(StdStrBuf &rsString, ValidationOption eOption);
51
52 inline bool ValidateFilename(char *szFilename, size_t iMaxSize = _MAX_PATH) { return ValidateString(szString: szFilename, eOption: VAL_Filename, iMaxSize); }
53}
54
55// Validation adapter: Call ValidateString on string after compiling it
56template <class T> struct C4StrValAdapt
57{
58 T &rValue; C4InVal::ValidationOption eValType;
59
60 explicit C4StrValAdapt(T &rValue, C4InVal::ValidationOption eValType) : rValue(rValue), eValType(eValType) {}
61
62 inline void CompileFunc(StdCompiler *pComp)
63 {
64 pComp->Value(rValue);
65 if (pComp->isCompiler()) C4InVal::ValidateString(rValue.GetObj(), eValType); // works on Par adapt only :(
66 }
67
68 template <class D> inline bool operator==(const D &nValue) const { return rValue == nValue; }
69 template <class D> inline C4StrValAdapt<T> &operator=(const D &nValue) { rValue = nValue; return *this; }
70};
71
72template <class T> inline C4StrValAdapt<T> mkStrValAdapt(T &&rValue, C4InVal::ValidationOption eValType) { return C4StrValAdapt<T>(rValue, eValType); }
73
74// StdStrBuf that validates on compilation
75struct ValidatedStdStrBufBase : public StdStrBuf
76{
77 ValidatedStdStrBufBase(const char *szCopy) : StdStrBuf(szCopy) {}
78 ValidatedStdStrBufBase() : StdStrBuf() {}
79
80 inline void CompileFunc(StdCompiler *pComp, int iRawType = 0)
81 {
82 pComp->Value(rStruct: mkParAdapt(rObj&: static_cast<StdStrBuf &>(*this), rPar: iRawType));
83 if (pComp->isCompiler()) Validate();
84 }
85
86 virtual bool Validate() = 0;
87
88 void CopyValidated(const char *szFromVal)
89 {
90 Copy(pnData: szFromVal);
91 Validate();
92 }
93
94 void CopyValidated(const StdStrBuf &sFromVal)
95 {
96 Copy(Buf2: sFromVal);
97 Validate();
98 }
99
100 virtual ~ValidatedStdStrBufBase() {}
101};
102
103template <C4InVal::ValidationOption V> struct ValidatedStdStrBuf : public ValidatedStdStrBufBase
104{
105 ValidatedStdStrBuf(const char *szCopy) : ValidatedStdStrBufBase(szCopy) {}
106 ValidatedStdStrBuf() : ValidatedStdStrBufBase() {}
107
108 virtual bool Validate() override
109 {
110 return C4InVal::ValidateString(*this, V);
111 }
112
113 template <class D> inline bool operator==(const D &nValue) const { return static_cast<const StdStrBuf &>(*this) == nValue; }
114 template <class D> inline ValidatedStdStrBuf<V> &operator=(const D &nValue) { static_cast<StdStrBuf &>(*this) = nValue; return *this; }
115};
116