0

I have written a C code to read from a input file and write into an output file.

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>




int callreadwrite(char *infile, char *outfile) {

   FILE *fi, *fo;
   char *line = NULL, *line1 = NULL, *line2 = NULL, *line3 = NULL, *line4 = NULL, *line5 = NULL, *line6 = NULL,*baseline1 = "Count";

    size_t len = 0;
    ssize_t read;
    int i = 0, countt, klent, tlenn, neq_vctr = 0, n = 0, res = 0, fin = 0, Nlenn, c;

    unsigned char *count, *klen, *tlen, *key, *msg, *nmac;

    time_t ltime; // calendar time 
    ltime = time(NULL); // get current cal time 

    fi = fopen(infile, "r");
    fo = fopen(outfile, "w");



    while ((read = getline(&line1, &len, fi)) != -1) {

      if (strncmp(baseline1, line1, 5) == 0) {
        getline(&line2, &len, fi);
        getline(&line3, &len, fi);
        getline(&line4, &len, fi);
        getline(&line5, &len, fi);
        getline(&line6, &len, fi);

        count = line1 + 8;
        klen = line2 + 7;
        tlen = line3 + 7;
        key = line4 + 6;
        msg = line5 + 6;
        nmac = line6 + 6;
         // convert string to integer: count, key length, message length, tag length
        countt = strtol(count, NULL, 0);
        fprintf(fo, "Count = %d\n", countt);


        klent = strtol(klen, NULL, 0);
        fprintf(fo, "Klen = %d\n", klent);

        tlenn = strtol(tlen, NULL, 0);

        fprintf(fo, "Count = %d\n", countt);
        fprintf(fo, "Klen = %d\n", klent);
        fprintf(fo, "Tlen = %d\n", tlenn);
        fprintf(fo, "Key = %s", key);
        fprintf(fo, "Msg = %s", msg);
        fprintf(fo, "Nmac = %s", nmac);




     }

 }

 fclose(fi);
 fclose(fo);

 return 0;

}




int main() {
     callreadwrite("read.txt", "write.txt");

}

The program copies the content of input file to output file.If the contents of input files are as follows

Count = 0
Klen = 10
Tlen = 10
Key = 82f3b69a1bff4de15c33
Msg = fcd6d98bef45ed6850806e96f255fa0c8114b72873abe8f43c10bea7c1df706f10458e6d4e1c9201f057b8492fa10fe4b541d0fc9d41ef839acff1bc76e3fdfebf2235b5bd0347a9a6303e83152f9f8db941b1b94a8a1ce5c273b55dc94d99a171377969234134e7dad1ab4c8e46d18df4dc016764cf95a11ac4b491a2646be1
Mac = 1ba0e66cf72efc349207

Count = 1
Klen = 10
Tlen = 10
Key = 4766e6fe5dffc98a5c50
Msg = d68b828a153f5198c005ee36c0af2ff92e84907517f01d9b7c7993469df5c21078fa356a8c9715ece2414be94e10e547f32cbb8d0582523ed3bb0066046e51722094aa44533d2c876e82db402fbb00a6c2f2cc3487973dfc1674463e81e42a39d9402941f39b5e126bafe864ea1648c0a5be0a912697a87e4f8eabf79cbf130e
Mac = 007e4504041a12f9e345

But when the input file contains one more entry its gives error

Count = 3
Klen = 142
Tlen = 64
Key = f78343071f61ee7d9f791bd53132e6d557928bcfe4b214bebf6f3592e46374c7ab148c3c4d6a1443a4675cf4321298c865b440631947b6b05f2c2a337d1cbb9b3661de974b4604eb41cc77c3659e85470e47e16f22a34619db935d59cbf5e1101ed401c020db069eff1035e9d1bff77bd8b3379e05ac0c20bc0e98aad7d7304dedd3bc5ed4136184649b5e0f7e5b
Msg = d63b50b54e1536e35d5f3c6e29f1e49a78ca43fa22b31232c71f0300bd56517e4cd29ba11ee9f206f1ad31ee8f118c87004d6c6dfe837b70a9a2fa987c8b5b6680720c5dbf8791c1fcd6d59fa16cc20df9bc0fb39f41598a376476e45b9f06add8e34af01b373a9ce6a3d189484cacb6cbe0d3d5ef34d709d72c1dee43dc79da
Mac = 086f674d778db491e73b6fbc5126233c6b6e1f066963356d49ea386d9c0868ad25bf6edad0371cde87cea94a18c6dba47535dfce2e40d2246ab17980495d656c

The the error is as follows

 *** Error in `./aout': munmap_chunk(): invalid pointer: 0x0000000000b70810 ***
   ======= Backtrace: =========
   /lib/x86_64-linux-gnu/libc.so.6(+0x777e5)[0x7f23e8d397e5]


  ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
  Aborted (core dumped)

Can anyone plz let me know how to make the pointer map the correct location while reading.

4
  • You should really step through the code, line by line, in a debugger so you can narrow down the location of the crash. Commented Apr 18, 2017 at 11:54
  • Why is it important to copy "record by record", why not just copy all the lines? This way is more brittle if e.g. the file is missing a line or something. Commented Apr 18, 2017 at 11:56
  • Doesn't your compiler fire tons of warnings? Commented Apr 18, 2017 at 12:02
  • I think your reading the blankline between entries as data. You need an extra getline() call to skip past it. Commented Apr 18, 2017 at 13:08

2 Answers 2

3

Your main problem is with getline. getline will allocate a buffer and reallocate it. You give it a pointer for each line, but you use a single len variable.

On subsequent calls, len will be interpreted as the length of the current buffer, but that is not so. Consequently, a len larger than the current buffer, with a line that would fit that buffer according to len, may overwrite memory, causing undefined behavior.

Sign up to request clarification or add additional context in comments.

Comments

2

The problem is with your handling of the getline() function. It will allocate storage for you, but only under specific conditions:

  • lineptr == NULL and len == 0: Allocate the space needed
  • len != 0: Reallocate space if not large enough

In your case you initialize the line pointers, but you use the same len variable for all the reads. The getline() function uses that len to keep track of how much space it has allocated, so it needs a len for each of the lines.

The simplest solution is to create a separate len variable for every line.

size_t len1 = 0, len2 = 0, len3 = 0, len4 = 0, len5 = 0, len6 = 0;

while ((read = getline(&line1, &len1, fi)) != -1) {
  if (strncmp(baseline1, line1, 5) == 0) {
    getline(&line2, &len2, fi);
    getline(&line3, &len3, fi);
    getline(&line4, &len4, fi);
    getline(&line5, &len5, fi);
    getline(&line6, &len6, fi);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.