Skip to content
This repository was archived by the owner on Jun 15, 2023. It is now read-only.

Commit 0c2982d

Browse files
committed
fix not respecting length
1 parent 99a7209 commit 0c2982d

File tree

1 file changed

+18
-14
lines changed

1 file changed

+18
-14
lines changed

src/util.cc

+18-14
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ bool CanonicalizePath(string* path, unsigned int* slash_bits, string* err) {
9898
}
9999

100100
#ifdef _WIN32
101-
unsigned int ShiftOverBit(int offset, unsigned int bits) {
101+
static unsigned int ShiftOverBit(int offset, unsigned int bits) {
102102
// e.g. for |offset| == 2:
103103
// | ... 9 8 7 6 5 4 3 2 1 0 |
104104
// \_________________/ \_/
@@ -124,25 +124,29 @@ bool CanonicalizePath(char* path, size_t* len, unsigned int* slash_bits,
124124
char* components[kMaxPathComponents];
125125
int component_count = 0;
126126

127+
char* start = path;
128+
char* dst = start;
129+
const char* src = start;
130+
const char* end = start + *len;
131+
127132
#ifdef _WIN32
128133
// kMaxPathComponents protects this from overflowing.
129134
unsigned int bits = 0;
130-
int bits_offset = 0;
131-
for (char* c = path; (c = strpbrk(c, "/\\")) != NULL;) {
132-
if (static_cast<size_t>(c - path) >= *len)
133-
break;
134-
bits |= (*c == '\\') << bits_offset;
135-
*c++ = '/';
136-
bits_offset++;
135+
unsigned int bits_mask = 1;
136+
// Convert \ to /, setting a bit in |bits| for each \ encountered.
137+
for (char* c = path; c < end; ++c) {
138+
switch (*c) {
139+
case '\\':
140+
bits |= bits_mask;
141+
*c = '/';
142+
// Intentional fallthrough.
143+
case '/':
144+
bits_mask <<= 1;
145+
}
137146
}
138-
bits_offset = 0;
147+
int bits_offset = 0;
139148
#endif
140149

141-
char* start = path;
142-
char* dst = start;
143-
const char* src = start;
144-
const char* end = start + *len;
145-
146150
if (*src == '/') {
147151
#ifdef _WIN32
148152
bits_offset++;

0 commit comments

Comments
 (0)