- Feature Articles
- CodeSOD
- Error'd
- Forums
-
Other Articles
- Random Article
- Other Series
- Alex's Soapbox
- Announcements
- Best of…
- Best of Email
- Best of the Sidebar
- Bring Your Own Code
- Coded Smorgasbord
- Mandatory Fun Day
- Off Topic
- Representative Line
- News Roundup
- Editor's Soapbox
- Software on the Rocks
- Souvenir Potpourri
- Sponsor Post
- Tales from the Interview
- The Daily WTF: Live
- Virtudyne
Admin
Now seriously, if you were going through code and saw someone appending a 1=1 out of nowhere, you'd scratch your head and pull that face sitting at the top left hand corner of this website.
Admin
I see you're great writing SQL injection prone code (and killing at the same time the database...).
W T F ? ? ?
Admin
Is it injection-prone? Or have the lists of parameters been sanitized prior to this point in the code? You don't know.
Admin
"I see you're great writing SQL injection prone code (and killing at the same time the database...)."
Would you care to explain yourself? And while you're explaining yourself, make sure:
you've a basic idea what the database provided API's "quoting" function does, and how it helps prevent injections on any external data.
prepared statements will add overhead, versus reduce it, for PHP/ASP/CGI applications, as no data is shared and thus the statement is prepared every time.
I hate repeating myself, but obviously I'm not in a smart company (actually, I'm truly disappointed by the comments on this article, let's say it makes me think lower of this entire site...).
Admin
Grammarian: "Is it injection-prone? Or have the lists of parameters been sanitized prior to this point in the code? You don't know."
Hehe, shhh! Let's wipe years and years of successfully implementing safely applications running non-prepared queries, and claim anyone who doesn't prepare his statements, while using parameter wildcards is having injection prone SQL!
Because preparing is so cool, mon.
Admin
That statement is misleading. Prepared Statements (at least in the toy I use, MySQL) are prepared once per connection. That means that if I use a shared, persistent connection, I can cache a reference to the statement once per connection. It also means that if I have a kind of statement (e.g. getUser(id) -> "SELECT * FROM Users WHERE id=?") I can use it multiple times in a single request with different data without invoking the query parser every time.
But what do I know? I still think FastCGI is awesome.
Admin
"That statement is misleading. Prepared Statements (at least in the toy I use, MySQL) are prepared once per connection. That means that if I use a shared, persistent connection, I can cache a reference to the statement once per connection. It also means that if I have a kind of statement (e.g. getUser(id) -> "SELECT * FROM Users WHERE id=?") I can use it multiple times in a single request with different data without invoking the query parser every time."
Derrick, I guess noone is protected from being wrong, even the editors of WorseThanFailure.com
Sharing the connection AND sharing a previously prepared statement are two completely different things. It's not the first time I hear people confuse both.
Sure you can "reuse" the prepared statement in the same REQUEST, just how often do you do this in real applications? I've probably almost never done it. I'm doing web sites after all, and I don't have time retrieving my data piece by piece in multiple identical queries each request, now do I?
In the end, you end up preparing it, then running it once, and that's about all use of this prepared statement before the request is done.
To reuse a prepared statement, you need to be able to share the handle somehow between multiple requests which ALSO share the same connection. Java/C# (aka "real languages") have the benefit of being able to do this. PHP/old ASP/CGI on the other hand, can't do it, PHP doesn't even have a support for spawning or accessing the other requests threads, let alone passing resource handles among them.
Admin
"Prepared Statements (at least in the toy I use, MySQL) are prepared once per connection."
Oh also, Derrick: MySQL can't use the query cache when you use prepared statements. Did you know this?
Means if each request performs the same SELECT(s) (ex. retrieving the same articles and/or navigation for the page), without prepared statements you use the query cache, with them, the SELECT runs every time.
Now, sure, you could cache those yourself your business logic layer, but then the point of the superior performance of prepared statements becomes totally moot.
That's more of a flaw with MySQL than the concept of prepared statements (Postgres will apply caching to prepped statements), but it pays to research what's your DB actually doing while advocating those.
Admin
yeah, c is cool as it requires checking the buffer length. The lack of fake "true" condition in the "where" clause is a lightwieght. The real WTF is people still using C.
Admin
C isn't bad. I'm more shocked of people still using Pascal, or god forbid, Visual Basic.
C for dynamic web sites however ... that's a real WTF.
(Of course, it will run faster maybe, but that only means it will crash faster!!!! muhahahahahaa)
Admin
Main criciticms:
Also functions that return newly allocated buffers should be avoided, unless they begin with the word "create", which this one doesn't.
Better to have 2 functions, one to return the length and another that takes a pre-allocated buffer to write into. Let the caller manage the buffer.
Also not a good way to iterate through. Better to just use pointer arithmetic.
So how about this as a function to start to get the total length of all the strings.
Of course, easier with C++ where you can use ostringstream. Or Java, of course.
Admin
In C++ by the way, if we use "end" to mark the pointer to the null-terminating string, we can then do the copy in just one line:
If we input std::vector< std::string > in the first place then:
Oh how nice and simple.
Admin
One of the benefits of using C is that you can do both!
I am not a slashdot, but I play one on TV
Admin
I can't believe no one has used this cheap joke:
"and then?" "no and then" "and then?" "NO and then" "and then?" "NO AND THEN!"
Admin
I'm not confusing them. Last time I checked: in MySQL, prepared statements exist only in relation to a single connection. (Maybe that was just a limitation of PHP.) If you want to reuse a prepared statement across invocations, you have to keep the connection open and share it. Hence the mention of FastCGI: it makes it really easy to share resources like this; I've done it in both C++ and PHP.
cough Sorry, I'm choking on the bad habit you put in my mouth. There are use cases (which I also mentioned) where you do want to prepare a statement that is used multiple times with different data.
Yes, I realize this used to be true; it was because the Query Cache happens before the Query Compiler. There is a patch that was added last month that fixes this, however, by substituting the values into the prepared statement early. Unfortunately, it doesn't work very well with PREPARE...FROM statements; that's because of user variables, which the Query Cache can't handle, either.
On a similar note, the right place to do this kind of caching is usually not in the database, especially when the database lives on a different machine than the application. If you think the Query Cache is fast, try saving oft used, seldom writ results in something like memcache on the local host.
Admin
Not 40kb. 40kb would be easy. It was 40K LINES of code, weighing in significantly higher.
The copy and paste was always the starting point - very large portions which were then minorly tweaked for the specific situation, then copied and tweaked again. I'll call this process "inbreeding."
Yes - almost ALL the variables (at least the ones that didn't leak) were global. Arguments to functions were almost unheard of - if a function was called by an app, it was simply assumed that the variables it needed to access at the time had already been set.
Admin
So I take it I broke something somewhere (not surprising; it's been a while since I did C)?
The theory is that "termword" is a pointer that either contains the address of "whereword" or "andword". It is initially set to "whereword", but gets changed to "andword" if any term is received from the server.
That was the theory anyway.
So the last if should have been true iff none of the preceding if statements were true; i.e., none of the GetField() calls returned a value.
This would indicate that someone tried to bypass the security by sending a page with no fields. For the article example, if this were to happen, the SQL returns all rows in the database. For my intended design, it returns none, because the user that sent no fields is clearly a cheater who was trying to bypass security.
(This was supposed to address a potential problem I didn't like the other code because "WHERE 1=1" returns all the rows in the database if none of the GetField() calls returned a value, which seemed unsafe.)
Of course, my example doesn't address SQL injection at all (any more than the original article did). There needs to be something else to handle that.
Admin
Have you ever seen AWStats source code? No? Than you've never seen a Monolith.
Admin
I think I see some tool blame here.
The evil does not inhere in C. I've written object-oriented work in ANSI C. No arrows pointing to functions, true, but object oriented conceptually. Not a single function too long to be read and comprehended in a single screen. Any given file contained only functions specific to the object represented.
C is in fact ideally designed for good programming structure--put definitions in the header file, implemetation code in the related source.
So if the code in this app sprawled out to eternity in a single page, the fault lay with a brain-dead programmer, not with the language.
Captcha: yeah, there's got to be a twist.
Admin