Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people, just like you, are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
Solved

more secure read and write! how can i do this?

Posted on 2004-09-22
28
227 Views
Last Modified: 2010-04-01
Hello
in this program
i read one file

#include <iostream>
#include <fstream>
using namespace std;

int main(){
ifstream in ("Data/testtext.txt", ios::in);

if(!in) {
cout << "cannot open testtext.\n";
return 1;
}

char str[1000];
in.read(str, 999);
str[999] = '\0';
cout << ' ' << str;

in.close();
return 0;
}

in the file i have something like this

data2/somefolder/picture1
data2/somefolder/picture2

is it possible to put somewhere in the proggram
this
data2/somefolder/
so in the file i write only

picture1
picture2
...

my point here is to make more secure my proggram

thank you
0
Comment
Question by:sibas
  • 15
  • 12
28 Comments
 
LVL 11

Expert Comment

by:Jase-Coder
ID: 12122250
you could store the path in a constant or you could, you the windows API to get the current working directory

const char path[] = "data2/somefolder/picture1";

then you could do

strcat(path, filename);

I think this answer your question :S
0
 

Author Comment

by:sibas
ID: 12122623
Jase thanks, but is no way to working like this
first i am not working in windows
second i have more than 500 pictures to load
so to write 500 times
const char path[] = "data2/somefolder/picture1";
const char path[] = "data2/somefolder/picture2";
...
is a bit problem ;)
0
 
LVL 17

Expert Comment

by:rstaveley
ID: 12123709
Are the files numbered 1..500?

i.e.
--------8<--------
#include <iostream>
#include <fstream>
#include <cstdio>
using namespace std;

int main()
{
      for (int i = 1;i <= 500;i++) {
            char filename[1024],str[1000];
            sprintf(filename,"data2/somefolder/picture%d",i);
            ifstream in(filename);
            if (!in) {
                  cerr << "Error: Unable to open " << filename << '\n';
                  continue;
            }
            in.read(str,999);
            str[999] = '\0';
            cout << str;
      }
}
--------8<--------
0
Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

 

Author Comment

by:sibas
ID: 12123851
Thanks rstaveley
maybe i dont say in the right way what i want,
the pictures picture1, picture2, is only an example
is no way to know from begin the names of those pictures
maybe is sexygirl.png or nicemoon.gif
only the path i know
and because my proggram you can modify from internet
i have to make it more secure
thanks
0
 
LVL 17

Expert Comment

by:rstaveley
ID: 12124053
Do you want it to process all files in a directory?

> and because my proggram you can modify from internet

You mean to say that your program can be edited and recompiled?? What are you guarding against?
0
 

Author Comment

by:sibas
ID: 12124117
i mean my program can read pictures from internet
when they stored in text file from internet,
but this is big risk if someone gives another path
i hope you realize what i mean
0
 
LVL 17

Expert Comment

by:rstaveley
ID: 12124437
Ah I understand. You'll need to look for '/' to prevent people from getting clever with filenames like ../../../etc/passwd or whatever. You open a file with a bunch of filenames separated by newline characters.

--------8<--------
#include <iostream>
#include <fstream>
#include <string>
using namespace std;

int main(int argc,const char *argv[])
{
/* Open a file, which contains a list of filenames separated by newlines, specified at command line */
     if (argc < 2)
          return 1;
     ifstream filenames(*++argv);
     if (!filenames)
          return 1;
     string filename;
     while (getline(filenames,filename)) {
          if (filename.find('/') != string::npos)
               continue; // Path has a '/' - hacker reject!
          ifstream in(string("data2/somefolder/"+filename).c_str());
          if (!in) {
               cerr << "Error: Unable to open " << filename << '\n';
               continue;
          }
          // Your code from here....
          char str[1000];
          in.read(str,999);
          str[999] = '\0';
          cout << str;
     }
     return 0;
}
--------8<--------

Alternatively, for filenames separated by white space (i.e. no filenames with ' ' in them), use:
--------8<--------
     while (filenames >> filename) {
--------8<--------

This allows you to have more than one filename on the same line, which might be better for your CGI.
0
 

Author Comment

by:sibas
ID: 12131274
hi rstaveley
i try this, is really nice,
but somewhere i cant make it work
so i try like this
int main(int argc,const char *argv[])
{
ifstream in ("/home/tests/progr14a/data/Rrpictures", ios::in);
if(!in) {
cout << "cannot open Rrpictures.\n";
return 1;
}

     string filename;
     while (getline(in,filename)) {
          if (filename.find('/') != string::npos)
               continue; // Path has a '/' - hacker reject!
          ifstream in(string("data2/somefolder/"+filename).c_str());
          if (!in) {
              cerr << "Error: Unable to open " << filename << '\n';
               continue;
         }
          // Your code from here....
          char str[100];
         in.read(str,99);
          str[99] = '\0';
          cout << str;
     }
     return 0;
}

and i have this result

./readcpp
Error: Unable to open S10.jpg
Error: Unable to open s11.png

so this read the text but why it stop?

0
 
LVL 17

Expert Comment

by:rstaveley
ID: 12131464
If it cannot read the files, it may be because your working directory isn't the directory you expected. Try using an absolute path (one that starts with '/').

e.g.

          ifstream in(string("/home/sibas/data2/somefolder/"+filename).c_str());

You will of course need to make the path right for your system :-)


0
 

Author Comment

by:sibas
ID: 12131498
i try olso this but i have the same results

if you try to open a text working for you?
0
 
LVL 17

Expert Comment

by:rstaveley
ID: 12131654
Do you have permissions?
0
 

Author Comment

by:sibas
ID: 12131680
what you mean with this
i try with the same permissions that i have in my example,
for the text and dir
0
 
LVL 17

Accepted Solution

by:
rstaveley earned 125 total points
ID: 12132277
This works for me on FreeBSD and Linux with files in /home/rob/src/. :

read.cpp
-----8<-----
#include <iostream>
#include <fstream>
#include <string>

int main(int argc,const char *argv[])
{
        ifstream in ("/home/rob/src/files.txt", ios::in);
        if(!in) {
                cout << "cannot open Rrpictures.\n";
                return 1;
        }

     string filename;
     while (getline(in,filename)) {
          if (filename.find('/') != string::npos)
               continue; // Path has a '/' - hacker reject!
          ifstream in(string("/home/rob/src/"+filename).c_str());
          if (!in) {
              cerr << "Error: Unable to open " << filename << '\n';
               continue;
         }
          // Your code from here....
          char str[100];
         in.read(str,99);
          str[99] = '\0';
          cout << str;
     }
     return 0;
}
--------8<--------

What is your OS?
0
 

Author Comment

by:sibas
ID: 12132347
i am working with suse9
i try again but still i have problems
i will try latter and i let you know whats goin on
0
 

Author Comment

by:sibas
ID: 12158373
Hello  rstaveley
i accept your answer, but i cant make it work
i see the results like this
ÿØÿá
ÿØÿá

any idea about what is wrong
0
 
LVL 17

Expert Comment

by:rstaveley
ID: 12158554
They are binary files, and and cout is going to stop printing as soon as it finds a '\0' character in the char buffer. My guess is that ÿØÿá corresponds to something in your image file header, which is followed by a 0x00 byte.

You need to use raw binary mode, if you are going to output binary data to standard output.

There are of course many ways to do this, but I quite like using streambuf_iterators.

e.g.
--------8<--------
#include <iostream>
#include <fstream>
#include <iterator>
#include <string>

using namespace std;

int main(int argc,const char *argv[])
{
/* Open a file, which contains a list of filenames separated by newlines, specified at command line */
     if (argc < 2)
          return 1;
     ifstream filenames(*++argv);
     if (!filenames)
          return 1;
     string filename;
     while (getline(filenames,filename)) {
          if (filename.find('/') != string::npos)
               continue; // Path has a '/' - hacker reject!
          ifstream in(string("data2/somefolder/"+filename).c_str());
          if (!in) {
               cerr << "Error: Unable to open " << filename << '\n';
               continue;
          }
          typedef istreambuf_iterator<char> Iitr; /* Input stream buffer iterator */
          typedef ostreambuf_iterator<char> Oitr; /* Output stream buffer iterator */
          Iitr iend; /* This gives us an object which we can use to test end of input */
          Oitr oitr(cout); /* Output stream buffer iterator for standard output */
          size_t count = 0; /* We are only going to handle the first 99 bytes */
          for (Iitr iitr(in);iitr != iend;++iitr) {
               *oitr = *iitr;
               if (++count == 99) /* Stop after 99 characters - if there are > 99 characters in the file */
                     break;
          }
     }
     return 0;
}
--------8<--------

If you find that this looks a bit freaky, you can use:

  // get length of file:
  in.seekg (0, ios::end);
  int length = in.tellg();
  in.seekg (0, ios::beg);
  char buf[99];
  in.read(buf,min(99,length));
  cout.write(buf,length);
0
 

Author Comment

by:sibas
ID: 12158704
this is weird
but like this working

cout << filename << '\n';
0
 
LVL 17

Expert Comment

by:rstaveley
ID: 12158731
Was it the filename you wanted... not the contents of the file?
0
 

Author Comment

by:sibas
ID: 12158744
no the results is
B3.jpg
D10.jpg
D11.jpg

this is what i have in the text file
0
 

Author Comment

by:sibas
ID: 12158754
of course i am still have problem because is string end not char
0
 
LVL 17

Expert Comment

by:rstaveley
ID: 12159087
> this is what i have in the text file

...but you wanted the contents of files B3.jpg, D10.jpg etc. Right?
0
 

Author Comment

by:sibas
ID: 12159409
i try to say it again (so sorry my english is not so good)

my program read text files and display pictures, text, music, etc

so in pictures.txt i have

data2/somefolder/B3.jpg
data2/somefolder/D10.jpg
...

with
char str[1000];
in.read(str, 999);
str[999] = '\0';
cout << str;

my proggram working just fine

now what i try to find is

how to write in text file only the
B3.jpg
D10.jpg
...
and the rest path somewhere inside the
ifstream in(string("/home/rob/src/"+thistext).c_str()

and when i do
cout << str;
to display all the path like
/home/rob/src/B3.jpg
/home/rob/src/D10.jpg
...

i dont know many thinks about c c++ i like it and i do it for hobby
thank you and sorry if i am trouble
0
 
LVL 17

Expert Comment

by:rstaveley
ID: 12159557
I'm still having problems understanding your requirement.

From what can can gather, you start with input text file /home/tests/progr14a/data/Rrpictures, which contains a list of filenames with relative parths:

e.g.
  --------8<--------
  data2/somefolder/B3.jpg
  data2/somefolder/D10.jpg
  --------8<--------

You then want to create two output files.

(1) A list of files without their paths
e.g.
  --------8<--------
  B3.jpg
  D10.jpg
  --------8<--------

(2) A list of files with fully qualified paths
e.g.
  --------8<--------
  /home/tests/progr14a/data/B3.jpg
  /home/tests/progr14a/data/D10.jpg
  --------8<--------

If this is correct, let me know and I'll show you the code to do this. If I've misunderstood what you want, please could you describe what output files you want to create.
0
 

Author Comment

by:sibas
ID: 12159586
example

#include <iostream>
#include <fstream>
using namespace std;

int main(){
ifstream in ("Data/testtext.txt", ios::in);

HERE WE READ THE TEXT FILE, INSIDE
data2/somefolder/B3.jpg
data2/somefolder/D10.jpg
...

if(!in) {
cout << "cannot open testtext.\n";
return 1;
}

char str[1000];
in.read(str, 999);
str[999] = '\0';
cout << ' ' << str;

in.close();
return 0;
}

in the file i have something like this

data2/somefolder/picture1
data2/somefolder/picture2

is it possible to put somewhere in the proggram
this
data2/somefolder/
so in the file i write only

picture1
picture2
...
0
 

Author Comment

by:sibas
ID: 12159682
Yes i start with  /home/tests/progr14a/data/Rrpictures

inside the Rrpictures i have
  data2/somefolder/B3.jpg
  data2/somefolder/D10.jpg

with str i read this

  data2/somefolder/B3.jpg
  data2/somefolder/D10.jpg

and the proggram read the path and display the pictures

what i want is
in text file to write
B3.jpg
D10.jpg

and the rest path  /data2/somefolder/
to write somewhere inside the proggram

and when i do
cout << str;
then to display all the path
/data2/somefolder/B3.jpg
0
 
LVL 17

Expert Comment

by:rstaveley
ID: 12159723
I still don't understand what you want your output files to be.

Do you want everything written to standard output (i.e. cout)?
Do you want anything written to an output file?
0
 
LVL 17

Expert Comment

by:rstaveley
ID: 12159733
> and the rest path  /data2/somefolder/
> to write somewhere inside the proggram

That's the bit I can't understand. Do you mean you want to write this to a separate output file?
0
 

Author Comment

by:sibas
ID: 12159800
No i dont want it in seperate output file
i want something like

#include <iostream>
#include <fstream>
#include <string>

int main(int argc,const char *argv[])
{
    ifstream in (" /home/tests/progr14a/data/Rrpictures", ios::in);
        if(!in) {
                cout << "cannot open Rrpictures.\n";
                return 1;
        }

ifstream in(string("/data2/somefolder/"+TheNameOfPicture).c_str());

       
          char str[100];
          in.read(str,99);
          str[99] = '\0';
          cout << str;

//and the results of str must be /data2/somefolder/B3.jpg
...

     }
     return 0;
}

and the results of str must be /data2/somefolder/B3.jpg
...
0

Featured Post

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

IntroductionThis article is the second in a three part article series on the Visual Studio 2008 Debugger.  It provides tips in setting and using breakpoints. If not familiar with this debugger, you can find a basic introduction in the EE article loc…
This article shows you how to optimize memory allocations in C++ using placement new. Applicable especially to usecases dealing with creation of large number of objects. A brief on problem: Lets take example problem for simplicity: - I have a G…
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.

809 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question