Subscribe: The Daily WTF
http://syndication.thedailywtf.com/TheDailyWtf
Added By: Feedage Forager Feedage Grade C rated
Language: English
Tags:
buff size  buff  buffer      buffer  char  const  file  return      return  size      size  upgrade      return      
Rate this Feed
Rate this feedRate this feedRate this feedRate this feedRate this feed
Rate this feed 1 starRate this feed 2 starRate this feed 3 starRate this feed 4 starRate this feed 5 star

Comments (0)

Feed Details and Statistics Feed Statistics
Preview: The Daily WTF

The Daily WTF



Curious Perversions in Information Technology



Last Build Date: Tue, 17 Oct 2017 05:51:24 GMT

 



CodeSOD: RAM On Through

Mon, 16 Oct 2017 10:30:00 GMT

(image)

The company Tomasz worked for launched a new device line with more RAM than the previous generation. This was supposed to put an end to the sort of memory shortages common to embedded systems. However, it wasn't long before they began hearing from clients whose systems crashed whenever they attempted to upgrade the accompanying software package.

The initial reports were met with surprise and skepticism, but the investigation soon led Tomasz and his cohorts to—you guessed it—a reproducible out-of-memory error.

With RAM not an issue, they took a deeper look at the upgrade process itself. The 50MB upgrade package was supposed to be copied to a special directory so the OS could install it. In C++ on linux, this is a simple task. You could use splice() on a newer linux kernel, or sendfile() on an older one. You could also read and write one buffer at a time. Inefficient, but effective.

As you may already suspect, the developers who'd written the library for handling upgrades had taken a more brillant approach, shown below. readFile() stores the entire file in a string in memory, and writeFile() places it in the desired directory. With this implementation, any device could be brought to its knees with a large-enough upgrade file.

bool readFile(const char *filename, std::string &result)
{
    result.clear();
    FILE *fp=fopen(filename,"rb");

    if (!fp)
    {
        return false;
    }

    const size_t buff_size = 4 * 1024;
    char * buffer = (char *) malloc(buff_size);
    if (!buffer)
    {
        fclose(fp);
        return false;
    }

    size_t r = 0;
    do
    {
        r=fread(buffer,1,buff_size,fp);
        result.append(buffer,buffer+r);
    }
    while(r==buff_size);

    free(buffer);
    fclose(fp);

    return true;
}

bool writeFile(const char *file, const std::string & data )
{
    if(!file) return false;
    FILE *fp=fopen(file,"wb");
    if(!fp) return false;

    fwrite( data.c_str(), sizeof( char ), data.size(), fp );

    int r=ferror(fp);
    fclose(fp);
    return (r==0);
}
(image) [Advertisement] Release! is a light card game about software and the people who make it. Play with 2-5 people, or up to 10 with two copies - only $9.95 shipped!
(image)