Nmap Development mailing list archives

Re: grepable output bug


From: Michael Pattrick <mpattrick () rhinovirus org>
Date: Wed, 21 Jan 2009 13:01:28 -0500

On Wed, Jan 21, 2009 at 11:44 AM, MadHat Unspecific <madhat () unspecific com>
wrote:
Michael Pattrick wrote:
On Wed, Jan 21, 2009 at 12:42 AM, MadHat Unspecific
<madhat () unspecific com> wrote:
       p = grepvers;
       while((p = strchr(p, ','))) {
         p++;
       }

This time, if we match a ',' we just move to the next character in p
(p++;)
rather than replacing it with something else.  At least that is what I
think
it does.  I am a perl programmer by day, php by night and I hack C/C++
when
necessary, so I could be wrong, but it does work.

Hey MadHat,

That is exactly, what you are doing, but that wont change the state of
the string. You are simply moving where the pointer is pointing too.
If you want to erase all commas without replacing them with anything
you would have to do something like this:

p = grepvers;
  {
char * p2 = grepvers;

while(*p != NULL){
  if ( *p != ',' ){
    *p2 = *p;
    p2++;
  }
  p++;
}
  }

Although this is just an ugly spaghetti string hack.

First, there was a bug in my code, the while loop should be:
while(true){
  if( (*p) == NULL ){
    *p2 = NULL;
    break;
  }
  if ( (*p) != ',' ){
    *p2 = *p;
    p2++;
  }
  p++;
}
Which NULL terminates grepvers at the correct position.



Just for my own clarification, if I move the pointer ahead by one and
don't put anything in it's place, wouldn't it be effectively the same
thing? basically skipping the character.


In C/C++ an array is an immutable span of ram(immutable with respect to size
and element location), not a linked list. To represent this graphically:
+--------+-----+-----+-----+--------+
| memory | 10  | 11  | 12  |   13   |
+--------+-----+-----+-----+--------+
| value  | 'A' | ',' | 'B' |  NULL  |
+--------+-----+-----+-----+--------+

In this case, grepvers is a pointer containing a value representing the
start of our char array in ram:
grepvers = 10

We set 'p=grepvers', so now p == 10 and *p == 'A'. If we were to perform
'p++' then *p == ',' however the line p++ has no effect on grepvers because
it only serves to change where p is pointing, for example:
p++;
printf("%s - %s", grepvers, p);

would produce the following output:
A,B - ,B

The function 'strchr' will return a value equal to the memory location of
the first occurrence of a character in an array, but will not remove that
item from the array because array elements cannot be moved or removed. In
the code that I provided two pointers are used: one for reading and the
other for writing. The read pointer is moved forward on every iteration, the
write pointer which only writes and moves forward if the read pointer isnt
pointing at a comma. So it would produce output similar to this:

+--------+-----+-----+------+--------+
| memory | 10  | 11  |  12  |   13   |
+--------+-----+-----+------+--------+
| value  | 'A' | 'B' | NULL |  NULL  |
+--------+-----+-----+------+--------+

Element 13 remains in ram, although 12 is our new NULL termination and 13 is
unused we are unable to delete it without deleteing the whole array.

Here is a code sample:

#include<stdio.h>
#include<string.h>
int main(){
    char * p2, * p, grepvers[] = ",this,is,a,test,";
    printf("Origonal: %s\n",grepvers);
    p = grepvers;

    while((p = strchr(p, ','))) {
      p++;
    }
    printf("Strchr: %s\n",grepvers);

    p = grepvers;
    p2 = grepvers;

    while(true){
        if( (*p) == NULL ){
            *p2 = (*p);
            break;
        }
      if ( (*p) != ',' ){
        *p2 = *p;
        p2++;
      }
      p++;
    }
    printf("Spaghetti: %s\n",grepvers);
    return 0;
}

Which produces the following output:

Origonal: ,this,is,a,test,
Strchr: ,this,is,a,test,
Spaghetti: thisisatest

-- 
Michael Pattrick
http://www.rhinovirus.org/math

_______________________________________________
Sent through the nmap-dev mailing list
http://cgi.insecure.org/mailman/listinfo/nmap-dev
Archived at http://SecLists.Org


Current thread: