What's the most secure way to read a long int ?

Discussion in 'C++' started by Julien, Aug 13, 2011.

  1. Julien

    Julien Guest

    Hello,

    I used cppcheck to detect problems and had this :
    (warning) scanf without field width limits can crash with huge input data

    void read_cputime(double& cpu) {
    long int c;
    cpu = 0;
    FILE* f = fopen(CPU_TIME, "r");
    if (!f) return;
    int n = fscanf(f, "%ld",&c); <-- pb detected
    fclose(f);
    if (n != 1) return;
    cpu = c;
    }

    First I thought about adding a number in the format :
    int n = fscanf(f, "%4ld",&c);

    But I want the code to be portable (it must ok for 32 bits or 64 bits).
    So what to use ? A macro ? A c++ const ? C++ internal library (cin ?) ?
    other ?
    would a memset (c, 0, sizeof(c)) useful before ?

    Julien.
     
    Julien, Aug 13, 2011
    #1
    1. Advertising

  2. Julien

    Ian Collins Guest

    On 08/13/11 09:12 PM, Julien wrote:
    > Hello,
    >
    > I used cppcheck to detect problems and had this :
    > (warning) scanf without field width limits can crash with huge input data
    >
    > void read_cputime(double& cpu) {
    > long int c;
    > cpu = 0;
    > FILE* f = fopen(CPU_TIME, "r");
    > if (!f) return;
    > int n = fscanf(f, "%ld",&c);<-- pb detected
    > fclose(f);
    > if (n != 1) return;
    > cpu = c;
    > }
    >
    > First I thought about adding a number in the format :
    > int n = fscanf(f, "%4ld",&c);
    >
    > But I want the code to be portable (it must ok for 32 bits or 64 bits).
    > So what to use ? A macro ? A c++ const ? C++ internal library (cin ?) ?
    > other ?


    Do it the C++ way:

    std::ifstream f( CPU_TIME );
    if (!f) return;

    long c;
    f >> c;

    if(!f) return;

    --
    Ian Collins
     
    Ian Collins, Aug 13, 2011
    #2
    1. Advertising

  3. Julien

    Julien Guest

    >> ...
    >
    > Do it the C++ way:
    >
    > std::ifstream f( CPU_TIME );
    > if (!f) return;
    >
    > long c;
    > f >> c;
    >
    > if(!f) return;
    >

    Ok, cppcheck is mute about this now.

    What about for this kind of code ?
    time_t read_progress() {
    time_t stored_secs;
    FILE* f = fopen(PROGRESS_FN, "r");
    if (!f) return(0);
    int n = fscanf(f, "%ld",&stored_secs);
    fclose(f);
    if (n != 1) return(0);
    else return(stored_secs);
    }

    It's quite the same except the variable is a struct. So f >> stored_secs
    wouldn't work here.

    Julien
     
    Julien, Aug 13, 2011
    #3
  4. Julien

    Ian Collins Guest

    On 08/13/11 09:52 PM, Julien wrote:

    Please don't snip attributions, it's rude.

    > I wrote:


    >> Do it the C++ way:
    >>
    >> std::ifstream f( CPU_TIME );
    >> if (!f) return;
    >>
    >> long c;
    >> f>> c;
    >>
    >> if(!f) return;
    >>

    > Ok, cppcheck is mute about this now.
    >
    > What about for this kind of code ?


    It's horrible...

    > time_t read_progress() {
    > time_t stored_secs;
    > FILE* f = fopen(PROGRESS_FN, "r");
    > if (!f) return(0);
    > int n = fscanf(f, "%ld",&stored_secs);
    > fclose(f);
    > if (n != 1) return(0);
    > else return(stored_secs);
    > }
    >
    > It's quite the same except the variable is a struct. So f>> stored_secs
    > wouldn't work here.


    Which variable is a struct?

    Why do you want to do things the C way, rather than the more idiomatic
    C++ forms?

    fscanf requires you to get the types right, iostreams delegate the task
    to the compiler.

    --
    Ian Collins
     
    Ian Collins, Aug 13, 2011
    #4
  5. Julien

    Julien Guest

    Le 13/08/2011 12:57, Ian Collins a écrit :
    > On 08/13/11 09:52 PM, Julien wrote:
    >
    > Please don't snip attributions, it's rude.
    >

    Sorry for this. I've got to remember this.
    > ...
    >>> ...

    >> What about for this kind of code ?

    >
    > It's horrible...
    >
    >> time_t read_progress() {
    >> time_t stored_secs;
    >> FILE* f = fopen(PROGRESS_FN, "r");
    >> if (!f) return(0);
    >> int n = fscanf(f, "%ld",&stored_secs);
    >> fclose(f);
    >> if (n != 1) return(0);
    >> else return(stored_secs);
    >> }
    >>
    >> It's quite the same except the variable is a struct. So f>> stored_secs
    >> wouldn't work here.

    >
    > Which variable is a struct?

    Sorry, I made a mistake, time_t is not a struct but a datatype.
    > Why do you want to do things the C way, rather than the more idiomatic
    > C++ forms?
    >

    In fact, I try to correct cppcheck errors of a file on the internet
    which is C style whereas the file has cpp extension.
    I replaced the code above by this (the same way of the code you gave
    before) :
    time_t read_progress() {
    time_t stored_secs;
    std::ifstream f(CPU_TIME);
    if (!f) return 0;
    f >> stored_secs;
    if (!f) return 0;
    else return stored_secs;
    }

    > fscanf requires you to get the types right, iostreams delegate the task
    > to the compiler.

    Ok.
    Thank you for your help. I'll do other changes to use the C++ style.

    Sorry again for having snipped attributions (I never know if i cut too
    little or too much)

    Julien.
     
    Julien, Aug 13, 2011
    #5
  6. Julien

    Jorgen Grahn Guest

    On Sat, 2011-08-13, Ian Collins wrote:
    > On 08/13/11 09:52 PM, Julien wrote:

    ....
    >> int n = fscanf(f, "%ld",&stored_secs);

    ....

    > Why do you want to do things the C way, rather than the more idiomatic
    > C++ forms?


    To be fair to C, scanf() is not /the/ C way, just /a/ C way.
    In both languages, I prefer to do my own parsing, using strtol() and
    friends.

    /Jorgen

    --
    // Jorgen Grahn <grahn@ Oo o. . .
    \X/ snipabacken.se> O o .
     
    Jorgen Grahn, Aug 14, 2011
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Schnoffos
    Replies:
    2
    Views:
    1,220
    Martien Verbruggen
    Jun 27, 2003
  2. Daniel Rudy

    unsigned long long int to long double

    Daniel Rudy, Sep 19, 2005, in forum: C Programming
    Replies:
    5
    Views:
    1,194
    Peter Shaggy Haywood
    Sep 20, 2005
  3. pereges

    Promoting unsigned long int to long int

    pereges, Jun 30, 2008, in forum: C Programming
    Replies:
    112
    Views:
    2,089
    David Thompson
    Jul 28, 2008
  4. veryhotsausage
    Replies:
    1
    Views:
    1,809
    veryhotsausage
    Jul 4, 2008
  5. Oliver Graeser
    Replies:
    10
    Views:
    585
    Oliver Graeser
    Sep 26, 2008
Loading...

Share This Page