sibas
asked on
more secure read and write! how can i do this?
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
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
ASKER
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 ;)
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 ;)
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/so mefolder/p icture%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<--------
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/so
ifstream in(filename);
if (!in) {
cerr << "Error: Unable to open " << filename << '\n';
continue;
}
in.read(str,999);
str[999] = '\0';
cout << str;
}
}
--------8<--------
ASKER
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
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
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?
> 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?
ASKER
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
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
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,filenam e)) {
if (filename.find('/') != string::npos)
continue; // Path has a '/' - hacker reject!
ifstream in(string("data2/somefolde r/"+filena me).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.
--------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,filenam
if (filename.find('/') != string::npos)
continue; // Path has a '/' - hacker reject!
ifstream in(string("data2/somefolde
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.
ASKER
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/dat a/Rrpictur es", 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/somefolde r/"+filena me).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?
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/dat
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/somefolde
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?
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/dat a2/somefol der/"+file name).c_st r());
You will of course need to make the path right for your system :-)
e.g.
ifstream in(string("/home/sibas/dat
You will of course need to make the path right for your system :-)
ASKER
i try olso this but i have the same results
if you try to open a text working for you?
if you try to open a text working for you?
Do you have permissions?
ASKER
what you mean with this
i try with the same permissions that i have in my example,
for the text and dir
i try with the same permissions that i have in my example,
for the text and dir
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
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
i try again but still i have problems
i will try latter and i let you know whats goin on
ASKER
Hello rstaveley
i accept your answer, but i cant make it work
i see the results like this
ÿØÿá
ÿØÿá
any idea about what is wrong
i accept your answer, but i cant make it work
i see the results like this
ÿØÿá
ÿØÿá
any idea about what is wrong
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,filenam e)) {
if (filename.find('/') != string::npos)
continue; // Path has a '/' - hacker reject!
ifstream in(string("data2/somefolde r/"+filena me).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);
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,filenam
if (filename.find('/') != string::npos)
continue; // Path has a '/' - hacker reject!
ifstream in(string("data2/somefolde
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);
ASKER
this is weird
but like this working
cout << filename << '\n';
but like this working
cout << filename << '\n';
Was it the filename you wanted... not the contents of the file?
ASKER
no the results is
B3.jpg
D10.jpg
D11.jpg
this is what i have in the text file
B3.jpg
D10.jpg
D11.jpg
this is what i have in the text file
ASKER
of course i am still have problem because is string end not char
> this is what i have in the text file
...but you wanted the contents of files B3.jpg, D10.jpg etc. Right?
...but you wanted the contents of files B3.jpg, D10.jpg etc. Right?
ASKER
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
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/"
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
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.
From what can can gather, you start with input text file /home/tests/progr14a/data/
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/
/home/tests/progr14a/data/
--------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.
ASKER
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
...
#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
...
ASKER
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
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
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?
Do you want everything written to standard output (i.e. cout)?
Do you want anything written to an output file?
> 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?
> 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?
ASKER
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/somefold er/"+TheNa meOfPictur e).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
...
i want something like
#include <iostream>
#include <fstream>
#include <string>
int main(int argc,const char *argv[])
{
ifstream in (" /home/tests/progr14a/data/
if(!in) {
cout << "cannot open Rrpictures.\n";
return 1;
}
ifstream in(string("/data2/somefold
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
...
const char path[] = "data2/somefolder/picture1
then you could do
strcat(path, filename);
I think this answer your question :S