Use common (gcc/clang) security flags
[pp.git] / README.md
blob522511205bdb1b13e889f9e207e25251a252d23c
1 # pp (prepend)
3 The **pp** (prepend) utility takes the content of the file named by the *source* operand and inserts or prepends it
4 above the first line of the file named by the *target* operand. The file operands are processed in command-line order.
5 If the *source* file is a single dash (‘-’) or absent, **pp** reads from the standard input.
7 So, essentially, if I have a CSV file without a header and I want to quickly insert the header from a file, I
8 would run:
10 ```sh
11 $ pp header.txt spreadsheet.csv
12 ```
14 and it would be functionally equivalent to
16 ```sh
17 $ cat header.txt spreadsheet.csv > temp
18 $ mv temp spreadsheet.csv
19 ```
21 ## Features
22 * Quality
23     * Compiled with security hardening flags
24     * Static analysis integrated using clang's `scan-build` using checkers `alpha.security`, `alpha.core.CastSize`,
25     `alpha.core.CastToStruct`, `alpha.core.IdenticalExpr`, `alpha.core.PointerArithm`, `alpha.core.PointerSub`,
26     `alpha.core.SizeofPtr`, `alpha.core.TestAfterDivZero`, `alpha.unix`
27     * Test harness
28     * Follows [FreeBSD coding style](https://www.freebsd.org/cgi/man.cgi?query=style&sektion=9)
29 * Portable
30     * C99 compliant
31     * Self-contained, no external dependencies
32     * Easy to compile and uses POSIX make
34 ## Build dependencies
35 The only dependency is a toolchain supporting the following flags:
37 ```
38 CFLAGS = -std=c99 -O2 -Wall -Wextra -Wpedantic \
39         -Walloca -Wcast-qual -Wconversion -Wformat=2 -Wformat-security \
40         -Wnull-dereference -Wstack-protector -Wvla -Warray-bounds \
41         -Wbad-function-cast -Wconversion -Wshadow -Wstrict-overflow=4 -Wundef \
42         -Wstrict-prototypes -Wswitch-default -Wfloat-equal -Wimplicit-fallthrough \
43         -Wpointer-arith -Wswitch-enum \
44         -D_FORTIFY_SOURCE=2 \
45         -fstack-protector-strong -fPIE -fstack-clash-protection
47 LDFLAGS = -Wl,-z,relro -Wl,-z,now -Wl,-z,noexecstack -Wl,-z,separate-code
48 ```
50 Otherwise you can just remove the security flags and compile it with
51 ```
52 CFLAGS = -std=c99 -O2 -Wall -Wextra -Wpedantic
53 LDFLAGS =
54 ```
56 or pass your own flags to make
57 ```sh
58 make CC=gcc CFLAGS=... LDFLAGS=...
59 ```
61 ## Installation
62 Clone this repository then
64 ```sh
65 $ make PREFIX=/usr install
66 ```
68 This will install the compiled binary under `PREFIX` (`/usr/bin`) in this case, if not specified `PREFIX` will default
69 to `/usr/local`. For staged installs, `DESTDIR` is also supported. As the binary does not have any dependency it does
70 not have to be installed before use.
72 ## Usage
73 Using **pp** is quite simple, you just specify the *source* file and *target* file
74 ```sh
75 $ pp source target
76 ```
77 The source file however, can be omitted, in this case the program takes the input from the standard input until `EOF` or
78 `^D` is reached
79 ```sh
80 $ pp target
81 ```
82 this behavior can also be achieved by using ‘-’ as *source* file
83 ```sh
84 $ pp - target
85 ```
87 ## Compilation
88 In order to build on any Unix-like system, simply run `make`. Since the binary does not have any dependencies, it can
89 just be copied into your `PATH`.
91 ### Test suite
92 The test suite consists of a POSIX shell script called `harness.sh` contained in the `test` folder. It's output is
93 similar to [googletest](https://github.com/google/googletest)'s and it can be invoked with `make test` which, if
94 everything is working should output something similar to
95 ```
96 ./test/harness.sh
97 [----------] Test environment set-up.
98 [==========] Running 7 test cases.
99 [ RUN      ] empty_source
100 [       OK ] empty_source
101 [ RUN      ] empty_destination
102 [       OK ] empty_destination
103 [ RUN      ] trivial_test
104 [       OK ] trivial_test
105 [ RUN      ] stdin_source
106 [       OK ] stdin_source
107 [ RUN      ] utf8_source
108 [       OK ] utf8_source
109 [ RUN      ] filename_dash
110 [       OK ] filename_dash
111 [ RUN      ] opt_source
112 [       OK ] opt_source
113 [==========] 7 test cases ran.
114 [  PASSED  ] 7 tests.
115 [  FAILED  ] 0 tests.
116 [----------] Test environment teardown.
119 ### Static analysis
120 Static analysis on the code base is done by using clang's static analyzer run through `scan-build.sh` which wraps the
121 `scan-build` utility. The checkers used are part of the
122 [Experimental Checkers](https://releases.llvm.org/12.0.0/tools/clang/docs/analyzer/checkers.html#alpha-checkers)
123 (aka *alpha* checkers):
125 * `alpha.security`
126 * `alpha.core.CastSize`
127 * `alpha.core.CastToStruct`
128 * `alpha.core.IdenticalExpr`
129 * `alpha.core.PointerArithm`
130 * `alpha.core.PointerSub`
131 * `alpha.core.SizeofPtr`
132 * `alpha.core.TestAfterDivZero`
133 * `alpha.unix`