Skip to content

Commit

Permalink
fix(file): wierd fgetc/ungetc behavior on Windows
Browse files Browse the repository at this point in the history
  • Loading branch information
fumiama committed Apr 7, 2024
1 parent e2f64f4 commit da9b6a8
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 25 deletions.
4 changes: 2 additions & 2 deletions base16384.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,8 @@ union base16384_io_function_t {
typedef union base16384_io_function_t base16384_io_function_t;

struct base16384_stream_t {
const base16384_io_function_t f;
const void *client_data;
base16384_io_function_t f;
void *client_data;
};
/**
* @brief for stream encode/decode
Expand Down
20 changes: 16 additions & 4 deletions file.c
Original file line number Diff line number Diff line change
Expand Up @@ -248,10 +248,10 @@ base16384_err_t base16384_encode_stream_detailed(base16384_stream_t* input, base
return base16384_err_ok;
}

#define rm_head(fp) {\
int ch = fgetc(fp);\
if(ch == 0xFE) fgetc(fp);\
else ungetc(ch, fp);\
static inline void rm_head(FILE* fp) {
int ch = fgetc(fp);
if(ch == 0xFE) fgetc(fp);
else ungetc(ch, fp);
}

#define skip_offset(input_file) ((input_file[0]==(char)0xFE)?2:0)
Expand Down Expand Up @@ -299,9 +299,11 @@ base16384_err_t base16384_decode_file_detailed(const char* input, const char* ou
goto_base16384_file_detailed_cleanup(decode, base16384_err_fopen_input_file, {});
}
rm_head(fp);
#ifndef _WIN32 // windows is crazy and always throws EINVAL
if(errno) {
goto_base16384_file_detailed_cleanup(decode, base16384_err_read_file, {});
}
#endif
int cnt, last_encbuf_cnt = 0, last_decbuf_cnt = 0, offset = 0;
size_t total_decoded_len = 0;
while((cnt = fread(decbuf, sizeof(char), inputsize, fp)) > 0) {
Expand All @@ -316,7 +318,9 @@ base16384_err_t base16384_decode_file_detailed(const char* input, const char* ou
decbuf[cnt++] = '=';
decbuf[cnt++] = end;
}
#ifndef _WIN32 // windows is crazy and always throws EINVAL
if(errno) goto_base16384_file_detailed_cleanup(decode, base16384_err_read_file, {});
#endif
offset = decbuf[cnt-1];
last_decbuf_cnt = cnt;
cnt = base16384_decode_unsafe(decbuf, cnt, encbuf);
Expand Down Expand Up @@ -376,9 +380,11 @@ base16384_err_t base16384_decode_fp_detailed(FILE* input, FILE* output, char* en
off_t inputsize = _BASE16384_DECBUFSZ;
uint32_t sum = BASE16384_SIMPLE_SUM_INIT_VALUE;
rm_head(input);
#ifndef _WIN32 // windows is crazy and always throws EINVAL
if(errno) {
return base16384_err_read_file;
}
#endif
int cnt, last_encbuf_cnt = 0, last_decbuf_cnt = 0, offset = 0;
size_t total_decoded_len = 0;
while((cnt = fread(decbuf, sizeof(char), inputsize, input)) > 0) {
Expand All @@ -393,7 +399,9 @@ base16384_err_t base16384_decode_fp_detailed(FILE* input, FILE* output, char* en
decbuf[cnt++] = '=';
decbuf[cnt++] = end;
}
#ifndef _WIN32 // windows is crazy and always throws EINVAL
if(errno) return base16384_err_read_file;
#endif
offset = decbuf[cnt-1];
last_decbuf_cnt = cnt;
cnt = base16384_decode_unsafe(decbuf, cnt, encbuf);
Expand Down Expand Up @@ -464,9 +472,11 @@ base16384_err_t base16384_decode_fd_detailed(int input, int output, char* encbuf
else break;
}
uint16_t next = is_next_end_fd(input);
#ifndef _WIN32 // windows is crazy and always throws EINVAL
if(errno) {
return base16384_err_read_file;
}
#endif
if((uint16_t)(~next)) {
if(next&0xff00) {
decbuf[n++] = '=';
Expand Down Expand Up @@ -543,9 +553,11 @@ base16384_err_t base16384_decode_stream_detailed(base16384_stream_t* input, base
else break;
}
uint16_t next = is_next_end_stream(input);
#ifndef _WIN32 // windows is crazy and always throws EINVAL
if(errno) {
return base16384_err_read_file;
}
#endif
if((uint16_t)(~next)) {
if(next&0xff00) {
decbuf[n++] = '=';
Expand Down
16 changes: 6 additions & 10 deletions test/file_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,14 +97,14 @@ static char tstbuf[BASE16384_ENCBUFSZ];
for(i = TEST_SIZE; i > 0; i--) { \
reset_and_truncate(fd, i); \
\
int fdout = open(TEST_OUTPUT_FILENAME, O_RDWR|O_TRUNC|O_CREAT|O_APPEND); \
int fdout = open(TEST_OUTPUT_FILENAME, O_RDWR|O_TRUNC|O_CREAT|O_APPEND, 0644); \
loop_ok(!fdout, i, "open"); \
\
err = base16384_encode_fd_detailed(fd, fdout, encbuf, decbuf, flag); \
base16384_loop_ok(err); \
loop_ok(close(fd), i, "close"); \
\
int fdval = open(TEST_VALIDATE_FILENAME, O_WRONLY|O_TRUNC|O_CREAT); \
int fdval = open(TEST_VALIDATE_FILENAME, O_WRONLY|O_TRUNC|O_CREAT, 0644); \
loop_ok(!fdval, i, "open"); \
\
loop_ok(lseek(fdout, 0, SEEK_SET), i, "lseek"); \
Expand All @@ -124,7 +124,7 @@ static char tstbuf[BASE16384_ENCBUFSZ];
for(i = TEST_SIZE; i > 0; i--) { \
reset_and_truncate(fd, i); \
\
int fdout = open(TEST_OUTPUT_FILENAME, O_RDWR|O_TRUNC|O_CREAT|O_APPEND); \
int fdout = open(TEST_OUTPUT_FILENAME, O_RDWR|O_TRUNC|O_CREAT|O_APPEND, 0644); \
loop_ok(!fdout, i, "open"); \
\
err = base16384_encode_stream_detailed(&(base16384_stream_t){ \
Expand All @@ -137,7 +137,7 @@ static char tstbuf[BASE16384_ENCBUFSZ];
base16384_loop_ok(err); \
loop_ok(close(fd), i, "close"); \
\
int fdval = open(TEST_VALIDATE_FILENAME, O_WRONLY|O_TRUNC|O_CREAT); \
int fdval = open(TEST_VALIDATE_FILENAME, O_WRONLY|O_TRUNC|O_CREAT, 0644); \
loop_ok(!fdval, i, "open"); \
\
loop_ok(lseek(fdout, 0, SEEK_SET), i, "lseek"); \
Expand Down Expand Up @@ -171,19 +171,15 @@ static char tstbuf[BASE16384_ENCBUFSZ];
\
test_##name##_detailed(BASE16384_FLAG_NOHEADER|BASE16384_FLAG_SUM_CHECK_ON_REMAIN|BASE16384_FLAG_DO_SUM_CHECK_FORCELY);


#define remove_test_files() \
remove(TEST_INPUT_FILENAME); \
remove(TEST_OUTPUT_FILENAME); \
remove(TEST_VALIDATE_FILENAME);

int main() {
srand(time(NULL));

FILE* fp;
int fd, i;
base16384_err_t err;

init_test_files();

test_detailed(file);
test_detailed(fp);
test_detailed(fd);
Expand Down
24 changes: 22 additions & 2 deletions test/file_test.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

#include <stdint.h>

#define ok(has_failed, reason) \
if (has_failed) { \
perror(reason); \
Expand Down Expand Up @@ -83,15 +85,33 @@
}

#define init_input_file() \
for(i = 0; i < BASE16384_ENCBUFSZ; i += sizeof(int)) { \
*(int*)(&encbuf[i]) = rand(); \
fprintf(stderr, "fill encbufsz: %d\n", BASE16384_ENCBUFSZ);\
for(i = 0; i < BASE16384_ENCBUFSZ/sizeof(uint16_t); i++) { \
((uint16_t*)encbuf)[i] = (uint16_t)rand(); \
} \
fp = fopen(TEST_INPUT_FILENAME, "wb"); \
ok(!fp, "fopen"); \
ok(fwrite(encbuf, BASE16384_ENCBUFSZ, 1, fp) != 1, "fwrite"); \
ok(fclose(fp), "fclose"); \
fputs("input file created.\n", stderr);

#define init_test_files() {\
fd = open(TEST_INPUT_FILENAME, O_RDWR|O_TRUNC|O_CREAT, 0644); \
ok(fd<0, "open"); \
ok(close(fd), "close"); \
fd = open(TEST_OUTPUT_FILENAME, O_RDWR|O_TRUNC|O_CREAT, 0644); \
ok(fd<0, "open"); \
ok(close(fd), "close"); \
fd = open(TEST_VALIDATE_FILENAME, O_RDWR|O_TRUNC|O_CREAT, 0644); \
ok(fd<0, "open"); \
ok(close(fd), "close");

#define remove_test_files() \
remove(TEST_INPUT_FILENAME); \
remove(TEST_OUTPUT_FILENAME); \
remove(TEST_VALIDATE_FILENAME); \
}

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
Expand Down
14 changes: 7 additions & 7 deletions test/wrap_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ int main() {
int fd, i;
base16384_err_t err;

init_test_files();

fputs("testing base16384_en/decode_file...\n", stderr);
init_input_file();
for(i = TEST_SIZE; i > 0; i--) {
Expand Down Expand Up @@ -101,14 +103,14 @@ int main() {
for(i = TEST_SIZE; i > 0; i--) {
reset_and_truncate(fd, i);

int fdout = open(TEST_OUTPUT_FILENAME, O_RDWR|O_TRUNC|O_CREAT|O_APPEND);
int fdout = open(TEST_OUTPUT_FILENAME, O_RDWR|O_TRUNC|O_CREAT|O_APPEND, 0644);
loop_ok(!fdout, i, "open");

err = base16384_encode_fd(fd, fdout, encbuf, decbuf);
base16384_loop_ok(err);
loop_ok(close(fd), i, "close");

int fdval = open(TEST_VALIDATE_FILENAME, O_WRONLY|O_TRUNC|O_CREAT);
int fdval = open(TEST_VALIDATE_FILENAME, O_WRONLY|O_TRUNC|O_CREAT, 0644);
loop_ok(!fdval, i, "open");

loop_ok(lseek(fdout, 0, SEEK_SET), i, "lseek");
Expand All @@ -127,7 +129,7 @@ int main() {
for(i = TEST_SIZE; i > 0; i--) {
reset_and_truncate(fd, i);

int fdout = open(TEST_OUTPUT_FILENAME, O_RDWR|O_TRUNC|O_CREAT|O_APPEND);
int fdout = open(TEST_OUTPUT_FILENAME, O_RDWR|O_TRUNC|O_CREAT|O_APPEND, 0644);
loop_ok(!fdout, i, "open");

err = base16384_encode_stream(&(base16384_stream_t){
Expand All @@ -140,7 +142,7 @@ int main() {
base16384_loop_ok(err);
loop_ok(close(fd), i, "close");

int fdval = open(TEST_VALIDATE_FILENAME, O_WRONLY|O_TRUNC|O_CREAT);
int fdval = open(TEST_VALIDATE_FILENAME, O_WRONLY|O_TRUNC|O_CREAT, 0644);
loop_ok(!fdval, i, "open");

loop_ok(lseek(fdout, 0, SEEK_SET), i, "lseek");
Expand All @@ -160,9 +162,7 @@ int main() {
validate_result();
}

remove(TEST_INPUT_FILENAME);
remove(TEST_OUTPUT_FILENAME);
remove(TEST_VALIDATE_FILENAME);
remove_test_files();

return 0;
}

0 comments on commit da9b6a8

Please sign in to comment.