forked from nil0x42/duplicut
-
Notifications
You must be signed in to change notification settings - Fork 1
/
line.c
122 lines (112 loc) · 2.97 KB
/
line.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#include <string.h>
#include <ctype.h>
#include "line.h"
#include "const.h"
#include "debug.h"
#include "chunk.h"
#include "config.h"
/** True if `str` only contains printable chars
*/
static bool str_isprint(char *str, size_t size)
{
while (size--)
{
if (!isprint(str[size]))
return (false);
}
return (true);
}
/** True if `str` was filtered by line removal rules
*/
static bool filter_line(char *str, size_t size)
{
if (size > g_conf.line_max_size)
return (true);
else if (g_conf.filter_printable && !str_isprint(str, size))
return (true);
return (false);
}
/** Set `dst` to next line in `chunk`
* The function returns false when end-of-chunk is reached.
* You are not expected to understand this
*/
bool get_next_line(t_line *dst, t_chunk *chunk)
{
size_t size;
char *next;
size_t line_size;
size = chunk->endptr - chunk->ptr;
while (size > 0)
{
if (chunk->ptr[0] == DISABLED_LINE)
{
if ((next = memchr(chunk->ptr, '\n', size)) == NULL)
return (false);
size -= (next - chunk->ptr) + 1;
chunk->ptr = next + 1;
}
else if (chunk->ptr[0] == '\n')
{
size -= 1;
chunk->ptr += 1;
}
else if (chunk->ptr[0] == '\r' && size > 1 && chunk->ptr[1] == '\n')
{
size -= 2;
chunk->ptr += 2;
}
else if ((next = memchr(chunk->ptr, '\n', size)) == NULL)
{
if (filter_line(chunk->ptr, size))
return (false);
SET_LINE(*dst, chunk->ptr, size);
chunk->ptr += size;
return (true);
}
else
{
line_size = next - chunk->ptr;
if (chunk->ptr[line_size - 1] == '\r')
{
if (filter_line(chunk->ptr, line_size - 1))
{
chunk->ptr += line_size + 1;
size -= line_size + 1;
}
else
{
SET_LINE(*dst, chunk->ptr, line_size - 1);
chunk->ptr += line_size + 1;
return (true);
}
}
else
{
if (filter_line(chunk->ptr, line_size))
{
chunk->ptr += line_size + 1;
size -= line_size + 1;
}
else
{
SET_LINE(*dst, chunk->ptr, line_size);
chunk->ptr += line_size + 1;
return (true);
}
}
}
}
return (false);
}
/** Compare two t_line objects.
* If the function returns 0, then lines are equal
*/
int cmp_line(t_line *l1, t_line *l2)
{
int size;
size = LINE_SIZE(*l1);
if (LINE_SIZE(*l2) != size)
return (1);
else
return (memcmp(LINE_ADDR(*l1), LINE_ADDR(*l2), size));
}