Skip to content

Commit b8e708d

Browse files
authored
Fix bugs when reading big-endian u64 SAS catalog files (#293)
1 parent 75dce86 commit b8e708d

1 file changed

Lines changed: 16 additions & 14 deletions

File tree

src/sas/readstat_sas7bcat_read.c

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ static readstat_error_t sas7bcat_parse_value_labels(const char *value_start, siz
6060

6161
/* Pass 1 -- find out the offset of the labels */
6262
for (i=0; i<label_count_capacity; i++) {
63-
if (&lbp1[3] - value_start > value_labels_len || lbp1[2] < 0) {
63+
if (&lbp1[3] - value_start > value_labels_len || sas_read2(&lbp1[2], ctx->bswap) < 0) {
6464
retval = READSTAT_ERROR_PARSE;
6565
goto cleanup;
6666
}
@@ -76,7 +76,7 @@ static readstat_error_t sas7bcat_parse_value_labels(const char *value_start, siz
7676
}
7777
value_offset[label_pos] = lbp1 - value_start;
7878
}
79-
lbp1 += 6 + lbp1[2];
79+
lbp1 += 6 + sas_read2(&lbp1[2], ctx->bswap);
8080
}
8181

8282
const char *lbp2 = lbp1;
@@ -93,7 +93,7 @@ static readstat_error_t sas7bcat_parse_value_labels(const char *value_start, siz
9393
readstat_value_t value = { .type = is_string ? READSTAT_TYPE_STRING : READSTAT_TYPE_DOUBLE };
9494
char string_val[4*16+1];
9595
if (is_string) {
96-
size_t value_entry_len = 6 + lbp1[2];
96+
size_t value_entry_len = 6 + sas_read2(&lbp1[2], ctx->bswap);
9797
retval = readstat_convert(string_val, sizeof(string_val),
9898
&lbp1[value_entry_len-16], 16, ctx->converter);
9999
if (retval != READSTAT_OK)
@@ -143,18 +143,20 @@ static readstat_error_t sas7bcat_parse_block(const char *data, size_t data_size,
143143
readstat_error_t retval = READSTAT_OK;
144144

145145
size_t pad = 0;
146-
int label_count_capacity = 0;
147-
int label_count_used = 0;
146+
uint64_t label_count_capacity = 0;
147+
uint64_t label_count_used = 0;
148148
int payload_offset = 106;
149+
uint16_t flags = 0;
149150
char name[4*32+1];
150151

151152
if (data_size < payload_offset)
152153
goto cleanup;
153154

154-
pad = (data[2] & 0x08) ? 4 : 0; // might be 0x10, not sure
155+
flags = sas_read2(&data[2], ctx->bswap);
156+
pad = (flags & 0x08) ? 4 : 0; // might be 0x10, not sure
155157
if (ctx->u64) {
156-
label_count_capacity = sas_read4(&data[42+pad], ctx->bswap);
157-
label_count_used = sas_read4(&data[50+pad], ctx->bswap);
158+
label_count_capacity = sas_read8(&data[42+pad], ctx->bswap);
159+
label_count_used = sas_read8(&data[50+pad], ctx->bswap);
158160

159161
payload_offset += 32;
160162
} else {
@@ -169,7 +171,7 @@ static readstat_error_t sas7bcat_parse_block(const char *data, size_t data_size,
169171
pad += 16;
170172
}
171173

172-
if (((data[2] & 0x80) && !ctx->u64) || ((data[2] & 0x20) && ctx->u64)) { // has long name
174+
if (((flags & 0x80) && !ctx->u64) || ((flags & 0x20) && ctx->u64)) { // has long name
173175
if (data_size < payload_offset + pad + 32)
174176
goto cleanup;
175177

@@ -203,15 +205,15 @@ static readstat_error_t sas7bcat_augment_index(const char *index, size_t len, sa
203205
break;
204206

205207
if (xlsr[ctx->xlsr_O_offset] == 'O') {
206-
uint32_t page = 0, pos = 0;
208+
uint64_t page = 0, pos = 0;
207209
if (ctx->u64) {
208-
page = sas_read4(&xlsr[8], ctx->bswap);
209-
pos = sas_read4(&xlsr[16], ctx->bswap);
210+
page = sas_read8(&xlsr[8], ctx->bswap);
211+
pos = sas_read2(&xlsr[16], ctx->bswap);
210212
} else {
211-
page = sas_read2(&xlsr[4], ctx->bswap);
213+
page = sas_read4(&xlsr[4], ctx->bswap);
212214
pos = sas_read2(&xlsr[8], ctx->bswap);
213215
}
214-
ctx->block_pointers[ctx->block_pointers_used++] = ((uint64_t)page << 32) + pos;
216+
ctx->block_pointers[ctx->block_pointers_used++] = (page << 32) + pos;
215217
}
216218

217219
if (ctx->block_pointers_used == ctx->block_pointers_capacity) {

0 commit comments

Comments
 (0)