Skip to content

Commit 04479a5

Browse files
committed
Make hardened builds by default because we can.
Properly convert label to CP850.
1 parent e2ce959 commit 04479a5

File tree

4 files changed

+137
-31
lines changed

4 files changed

+137
-31
lines changed

Makefile

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,20 @@ TARGET := $(notdir $(CURDIR))
55
BUILD := build
66
INCLUDES := include
77
SOURCES := source
8-
DEFINES :=
8+
DEFINES := -D_FORTIFY_SOURCE=2
99

1010

1111
# Compiler settings
1212
ARCH :=
13-
CFLAGS := $(ARCH) -std=c17 -O2 -g -fstrict-aliasing \
14-
-ffunction-sections -fdata-sections -Wall -Wextra \
15-
-Wstrict-aliasing=2
16-
CXXFLAGS := $(ARCH) -std=c++20 -O2 -g -fstrict-aliasing \
17-
-ffunction-sections -fdata-sections -Wall -Wextra \
18-
-Wstrict-aliasing=2
19-
ASFLAGS := $(ARCH) -O2 -g -x assembler-with-cpp
13+
CFLAGS := $(ARCH) -std=c17 -O2 -g -fPIE -fstrict-aliasing \
14+
-ffunction-sections -fdata-sections -fstack-protector-strong \
15+
-Wall -Wextra -Wstrict-aliasing=2
16+
CXXFLAGS := $(ARCH) -std=c++20 -O2 -g -fPIE -fstrict-aliasing \
17+
-ffunction-sections -fdata-sections -fstack-protector-strong \
18+
-Wall -Wextra -Wstrict-aliasing=2
19+
ASFLAGS := $(ARCH) -O2 -g -fPIE -x assembler-with-cpp
2020
ARFLAGS := -rcs
21-
LDFLAGS := $(ARCH) -O2 -s -Wl,--gc-sections
21+
LDFLAGS := $(ARCH) -O2 -s -pie -fPIE -Wl,--gc-sections,-z,relro,-z,now,-z,noexecstack
2222

2323
PREFIX :=
2424
CC := $(PREFIX)gcc

include/fat_label.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#pragma once
2+
3+
#include "types.h"
4+
5+
6+
7+
size_t convertCheckLabel(const char *const label, char *dosLabel);

source/fat_label.cpp

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
#include <cstdio>
2+
#include <cstdlib>
3+
#include <cwctype>
4+
#include "types.h"
5+
6+
7+
// http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP850.TXT
8+
// Range 0x80-0xFF.
9+
static const wchar_t cp850Lut[128] =
10+
{
11+
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7,
12+
0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
13+
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9,
14+
0x00FF, 0x00D6, 0x00DC, 0x00F8, 0x00A3, 0x00D8, 0x00D7, 0x0192,
15+
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA,
16+
0x00BF, 0x00AE, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
17+
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00C1, 0x00C2, 0x00C0,
18+
0x00A9, 0x2563, 0x2551, 0x2557, 0x255D, 0x00A2, 0x00A5, 0x2510,
19+
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x00E3, 0x00C3,
20+
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x00A4,
21+
0x00F0, 0x00D0, 0x00CA, 0x00CB, 0x00C8, 0x0131, 0x00CD, 0x00CE,
22+
0x00CF, 0x2518, 0x250C, 0x2588, 0x2584, 0x00A6, 0x00CC, 0x2580,
23+
0x00D3, 0x00DF, 0x00D4, 0x00D2, 0x00F5, 0x00D5, 0x00B5, 0x00FE,
24+
0x00DE, 0x00DA, 0x00DB, 0x00D9, 0x00FD, 0x00DD, 0x00AF, 0xACCE,
25+
0x00AD, 0x00B1, 0x2017, 0x00BE, 0x00B6, 0x00A7, 0x00F7, 0x00B8,
26+
0x00B0, 0x00A8, 0x00B7, 0x00B9, 0x00B3, 0x00B2, 0x25A0, 0x00A0
27+
};
28+
29+
30+
31+
// Make sure dosStr is big enough!
32+
static bool wchar2cp850(const wchar_t *wStr, char *dosStr)
33+
{
34+
while(*wStr != L'\0')
35+
{
36+
const wchar_t wc = *wStr++;
37+
if(wc > 0 && wc < 128)
38+
{
39+
*dosStr++ = wc;
40+
continue;
41+
}
42+
43+
unsigned i;
44+
for(i = 0; i < 128; i++)
45+
{
46+
if(wc == cp850Lut[i])
47+
{
48+
*dosStr++ = 0x80 | i;
49+
break;
50+
}
51+
}
52+
53+
if(i == 128)
54+
{
55+
fprintf(stderr, "Error: Can't convert wide character 0x%08" PRIX32 " to CP850.\n", wc);
56+
return false;
57+
}
58+
}
59+
60+
*dosStr = '\0';
61+
62+
return true;
63+
}
64+
65+
size_t convertCheckLabel(const char *const label, char *dosLabel)
66+
{
67+
// Reserve one more char so we can detect if the label is too long.
68+
wchar_t wLabel[13];
69+
wLabel[12] = L'\0';
70+
const size_t wideChars = mbstowcs(wLabel, label, 12);
71+
if(wideChars == (size_t)-1)
72+
{
73+
fputs("Failed to convert label to wide characters.\n", stderr);
74+
return 0;
75+
}
76+
77+
if(wideChars > 11)
78+
{
79+
fputs("Error: Label is too long.\n", stderr);
80+
return 0;
81+
}
82+
83+
for(unsigned i = 0; wLabel[i] != L'\0'; i++)
84+
{
85+
if(iswlower(wLabel[i]) != 0)
86+
{
87+
fputs("Warning: Label contains lowercase characters.\n", stderr);
88+
break;
89+
}
90+
}
91+
92+
if(!wchar2cp850(wLabel, dosLabel)) return 0;
93+
94+
if(*dosLabel == ' ')
95+
{
96+
fputs("Error: First character in label must nut be a space.\n", stderr);
97+
return 0;
98+
}
99+
100+
while(*dosLabel != '\0')
101+
{
102+
const unsigned char c = *dosLabel++;
103+
if(c < 0x20 || c == 0x22 ||
104+
(c >= 0x2A && c <= 0x2C) ||
105+
c == 0x2E || c == 0x2F ||
106+
(c >= 0x3A && c <= 0x3F) ||
107+
(c >= 0x5B && c <= 0x5D) ||
108+
c == 0x7C)
109+
{
110+
fputs("Error: Label contains invalid characters.\n", stderr);
111+
return 0;
112+
}
113+
}
114+
115+
return wideChars;
116+
}

source/main.cpp

Lines changed: 5 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1+
#include <clocale>
12
#include <cstdio>
23
#include <cstdlib>
34
#include <cstring>
45
#include <exception>
56
#include <getopt.h>
67
#include "errors.h"
78
#include "format.h"
9+
#include "fat_label.h"
810
#include "verbose_printf.h"
911

1012

@@ -32,6 +34,8 @@ static void printHelp(void)
3234

3335
int main(const int argc, char *const argv[])
3436
{
37+
setlocale(LC_CTYPE, ""); // We could also default to "en_US.UTF-8".
38+
3539
static const struct option long_options[] =
3640
{{"big-clusters", no_argument, NULL, 'b'},
3741
{ "capacity", required_argument, NULL, 'c'},
@@ -89,29 +93,8 @@ int main(const int argc, char *const argv[])
8993
break;
9094
case 'l':
9195
{
92-
if(strlen(optarg) > 11)
93-
{
94-
fputs("Error: Label is longer than 11 characters.\n", stderr);
96+
if(convertCheckLabel(optarg, label) == 0)
9597
return ERR_INVALID_ARG;
96-
}
97-
strncpy(label, optarg, 11);
98-
/*for(u32 i = 0; i < 11; i++)
99-
{
100-
const unsigned char lc = label[i];
101-
if(lc < 0x20 || lc == 0x22 ||
102-
(lc >= 0x2A && lc <= 0x2C) ||
103-
lc == 0x2E || lc == 0x2F ||
104-
(lc >= 0x3A && lc <= 0x3F) ||
105-
(lc >= 0x5B && lc <= 0x5D) ||
106-
lc == 0x7C)
107-
{
108-
fputs("Error: Label contains invalid characters.\n", stderr);
109-
return ERR_INVALID_ARG;
110-
}
111-
// TODO: The label should be encoded in the system's DOS code page. Convert from UTF-8 to DOS code page.
112-
// TODO: Check for uppercase chars and give a warning.
113-
// TODO: Do not allow the "NO NAME" label?
114-
}*/
11598
}
11699
break;
117100
case 'v':

0 commit comments

Comments
 (0)