1999-09-11 23:53:40 +00:00
|
|
|
/*
|
|
|
|
+----------------------------------------------------------------------+
|
2004-01-08 08:18:22 +00:00
|
|
|
| PHP Version 5 |
|
1999-09-11 23:53:40 +00:00
|
|
|
+----------------------------------------------------------------------+
|
2007-01-01 09:36:18 +00:00
|
|
|
| Copyright (c) 1997-2007 The PHP Group |
|
1999-09-11 23:53:40 +00:00
|
|
|
+----------------------------------------------------------------------+
|
2006-01-01 12:51:34 +00:00
|
|
|
| This source file is subject to version 3.01 of the PHP license, |
|
1999-09-11 23:53:40 +00:00
|
|
|
| that is bundled with this package in the file LICENSE, and is |
|
2003-06-10 20:04:29 +00:00
|
|
|
| available through the world-wide-web at the following url: |
|
2006-01-01 12:51:34 +00:00
|
|
|
| http://www.php.net/license/3_01.txt |
|
1999-09-11 23:53:40 +00:00
|
|
|
| If you did not receive a copy of the PHP license and are unable to |
|
|
|
|
| obtain it through the world-wide-web, please send a note to |
|
|
|
|
| license@php.net so we can mail you a copy immediately. |
|
|
|
|
+----------------------------------------------------------------------+
|
2002-11-25 12:30:28 +00:00
|
|
|
| Author: Hartmut Holzgraefe <hholzgra@php.net> |
|
1999-09-11 23:53:40 +00:00
|
|
|
+----------------------------------------------------------------------+
|
|
|
|
*/
|
|
|
|
/* $Id$ */
|
1999-09-11 23:47:16 +00:00
|
|
|
|
1999-11-09 13:57:11 +00:00
|
|
|
#include "php.h"
|
|
|
|
|
2000-08-17 13:17:14 +00:00
|
|
|
#include "php_globals.h"
|
|
|
|
|
1999-09-11 23:47:16 +00:00
|
|
|
#include <sys/types.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
2000-08-01 07:45:14 +00:00
|
|
|
#include "basic_functions.h"
|
|
|
|
#include "url_scanner.h"
|
1999-09-11 23:47:16 +00:00
|
|
|
|
2000-08-03 11:42:39 +00:00
|
|
|
#ifndef BUFSIZE
|
2000-08-01 07:45:14 +00:00
|
|
|
#define BUFSIZE 256
|
2000-08-03 11:42:39 +00:00
|
|
|
#endif
|
1999-09-11 23:47:16 +00:00
|
|
|
|
2001-08-26 11:49:43 +00:00
|
|
|
int php_url_scanner_activate(TSRMLS_D)
|
2000-09-19 17:37:34 +00:00
|
|
|
{
|
2000-08-01 07:45:14 +00:00
|
|
|
url_adapt(NULL,0,NULL,NULL);
|
2000-09-19 17:21:26 +00:00
|
|
|
return SUCCESS;
|
2000-08-01 07:45:14 +00:00
|
|
|
}
|
1999-09-11 23:47:16 +00:00
|
|
|
|
2000-09-19 17:37:34 +00:00
|
|
|
|
2001-08-26 11:49:43 +00:00
|
|
|
int php_url_scanner_deactivate(TSRMLS_D)
|
2000-09-19 17:37:34 +00:00
|
|
|
{
|
2000-08-01 07:45:14 +00:00
|
|
|
url_adapt(NULL,0,NULL,NULL);
|
2000-09-19 17:21:26 +00:00
|
|
|
return SUCCESS;
|
1999-09-18 12:16:16 +00:00
|
|
|
}
|
1999-09-11 23:47:16 +00:00
|
|
|
|
2001-06-06 13:06:12 +00:00
|
|
|
/* {{{ url_attr_addon
|
|
|
|
*/
|
2000-09-19 17:37:34 +00:00
|
|
|
static char *url_attr_addon(const char *tag,const char *attr,const char *val,const char *buf)
|
|
|
|
{
|
2000-08-01 07:45:14 +00:00
|
|
|
int flag = 0;
|
2001-07-28 11:36:37 +00:00
|
|
|
TSRMLS_FETCH();
|
1999-09-11 23:47:16 +00:00
|
|
|
|
2000-09-19 17:37:34 +00:00
|
|
|
if(!strcasecmp(tag,"a") && !strcasecmp(attr,"href")) {
|
2000-08-01 07:45:14 +00:00
|
|
|
flag = 1;
|
2000-08-01 20:21:35 +00:00
|
|
|
} else if(!strcasecmp(tag,"area" ) && !strcasecmp(attr,"href" )) {
|
2000-08-01 07:45:14 +00:00
|
|
|
flag = 1;
|
2000-08-01 20:21:35 +00:00
|
|
|
} else if(!strcasecmp(tag,"form" ) && !strcasecmp(attr,"action" )) {
|
2000-08-01 07:45:14 +00:00
|
|
|
flag = 1;
|
2000-08-01 20:21:35 +00:00
|
|
|
} else if(!strcasecmp(tag,"frame") && !strcasecmp(attr,"source" )) {
|
2000-08-01 07:45:14 +00:00
|
|
|
flag = 1;
|
2000-08-01 20:21:35 +00:00
|
|
|
} else if(!strcasecmp(tag,"img" ) && !strcasecmp(attr,"action" )) {
|
2000-08-01 07:45:14 +00:00
|
|
|
flag = 1;
|
|
|
|
}
|
2000-08-04 09:03:20 +00:00
|
|
|
if(flag) {
|
|
|
|
if(!strstr(val,buf)&&!strchr(val,':'))
|
2000-08-01 07:45:14 +00:00
|
|
|
{
|
2001-04-04 20:46:26 +00:00
|
|
|
char *result = (char *)emalloc(strlen(buf)+strlen(PG(arg_separator).output)+1);
|
2000-08-01 20:21:35 +00:00
|
|
|
int n;
|
|
|
|
|
|
|
|
if(strchr(val,'?')) {
|
2001-04-04 20:46:26 +00:00
|
|
|
strcpy(result,PG(arg_separator).output);
|
|
|
|
n=strlen(PG(arg_separator).output);
|
2000-08-01 20:21:35 +00:00
|
|
|
} else {
|
2000-08-03 11:42:39 +00:00
|
|
|
*result='?';
|
2000-08-01 20:21:35 +00:00
|
|
|
n=1;
|
|
|
|
}
|
2000-08-03 11:42:39 +00:00
|
|
|
strcpy(result+n,buf);
|
|
|
|
return result;
|
2000-08-01 07:45:14 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
2001-06-06 13:06:12 +00:00
|
|
|
/* }}} */
|
1999-09-11 23:47:16 +00:00
|
|
|
|
2000-08-01 07:45:14 +00:00
|
|
|
#define US BG(url_adapt_state)
|
2000-06-23 05:42:41 +00:00
|
|
|
|
2001-06-06 13:06:12 +00:00
|
|
|
/* {{{ url_adapt_ext
|
|
|
|
*/
|
2003-03-10 20:30:33 +00:00
|
|
|
char *url_adapt_ext(const char *src, uint srclen, const char *name, const char *val, size_t *newlen)
|
2000-09-19 17:21:26 +00:00
|
|
|
{
|
|
|
|
char buf[1024];
|
|
|
|
|
|
|
|
snprintf(buf, sizeof(buf)-1, "%s=%s", name, val);
|
|
|
|
|
|
|
|
return url_adapt(src, srclen, buf, newlen);
|
|
|
|
}
|
2001-06-06 13:06:12 +00:00
|
|
|
/* }}} */
|
2000-09-19 17:21:26 +00:00
|
|
|
|
2001-06-06 13:06:12 +00:00
|
|
|
/* {{{ url_adapt
|
|
|
|
*/
|
2000-08-01 07:45:14 +00:00
|
|
|
char *url_adapt(const char *src, size_t srclen, const char *data, size_t *newlen)
|
|
|
|
{
|
|
|
|
char *out,*outp;
|
2000-08-06 11:32:32 +00:00
|
|
|
int maxl,n;
|
2001-07-28 11:36:37 +00:00
|
|
|
TSRMLS_FETCH();
|
1999-09-11 23:47:16 +00:00
|
|
|
|
2000-08-01 07:45:14 +00:00
|
|
|
if(src==NULL) {
|
|
|
|
US.state=STATE_NORMAL;
|
2000-09-19 17:37:34 +00:00
|
|
|
if(US.tag) { efree(US.tag); US.tag =NULL; }
|
|
|
|
if(US.attr) { efree(US.attr); US.attr=NULL; }
|
|
|
|
if(US.val) { efree(US.val); US.val =NULL; }
|
2000-08-01 07:45:14 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
2000-06-23 05:42:41 +00:00
|
|
|
|
2000-08-01 07:45:14 +00:00
|
|
|
if(srclen==0)
|
|
|
|
srclen=strlen(src);
|
1999-09-11 23:47:16 +00:00
|
|
|
|
2000-08-01 07:45:14 +00:00
|
|
|
out=malloc(srclen+1);
|
|
|
|
maxl=srclen;
|
|
|
|
n=srclen;
|
1999-09-11 23:47:16 +00:00
|
|
|
|
2000-08-01 07:45:14 +00:00
|
|
|
*newlen=0;
|
|
|
|
outp=out;
|
1999-09-11 23:47:16 +00:00
|
|
|
|
2000-08-01 07:45:14 +00:00
|
|
|
while(n--) {
|
|
|
|
switch(US.state) {
|
|
|
|
case STATE_NORMAL:
|
|
|
|
if(*src=='<')
|
|
|
|
US.state=STATE_TAG_START;
|
|
|
|
break;
|
1999-09-11 23:47:16 +00:00
|
|
|
|
2000-08-01 07:45:14 +00:00
|
|
|
case STATE_TAG_START:
|
|
|
|
if(! isalnum(*src))
|
|
|
|
US.state=STATE_NORMAL;
|
|
|
|
US.state=STATE_TAG;
|
|
|
|
US.ml=BUFSIZE;
|
|
|
|
US.p=US.tag=erealloc(US.tag,US.ml);
|
|
|
|
*(US.p)++=*src;
|
|
|
|
US.l=1;
|
|
|
|
break;
|
1999-09-11 23:47:16 +00:00
|
|
|
|
2000-08-01 07:45:14 +00:00
|
|
|
case STATE_TAG:
|
|
|
|
if(isalnum(*src)) {
|
|
|
|
*(US.p)++ = *src;
|
|
|
|
US.l++;
|
|
|
|
if(US.l==US.ml) {
|
|
|
|
US.ml+=BUFSIZE;
|
|
|
|
US.tag=erealloc(US.tag,US.ml);
|
|
|
|
US.p = US.tag+US.l;
|
|
|
|
}
|
|
|
|
} else if (isspace(*src)) {
|
|
|
|
US.state = STATE_IN_TAG;
|
|
|
|
*US.p='\0';
|
|
|
|
US.tag=erealloc(US.tag,US.l);
|
|
|
|
} else {
|
|
|
|
US.state = STATE_NORMAL;
|
|
|
|
efree(US.tag);
|
|
|
|
US.tag=NULL;
|
|
|
|
}
|
|
|
|
break;
|
1999-09-11 23:47:16 +00:00
|
|
|
|
2000-08-01 07:45:14 +00:00
|
|
|
case STATE_IN_TAG:
|
|
|
|
if(isalnum(*src)) {
|
|
|
|
US.state=STATE_TAG_ATTR;
|
|
|
|
US.ml=BUFSIZE;
|
|
|
|
US.p=US.attr=erealloc(US.attr,US.ml);
|
|
|
|
*(US.p)++=*src;
|
|
|
|
US.l=1;
|
|
|
|
} else if (! isspace(*src)) {
|
|
|
|
US.state = STATE_NORMAL;
|
|
|
|
efree(US.tag);
|
|
|
|
US.tag=NULL;
|
|
|
|
}
|
1999-09-11 23:47:16 +00:00
|
|
|
break;
|
|
|
|
|
2000-08-01 07:45:14 +00:00
|
|
|
case STATE_TAG_ATTR:
|
|
|
|
if(isalnum(*src)) {
|
|
|
|
*US.p++=*src;
|
|
|
|
++US.l;
|
|
|
|
if(US.l==US.ml) {
|
|
|
|
US.ml+=BUFSIZE;
|
|
|
|
US.attr=erealloc(US.attr,US.ml);
|
|
|
|
US.p = US.attr+US.l;
|
|
|
|
}
|
|
|
|
if(US.l==US.ml) {
|
|
|
|
US.ml+=BUFSIZE;
|
|
|
|
US.attr=erealloc(US.attr,US.ml);
|
|
|
|
US.p = US.attr+US.l;
|
|
|
|
}
|
|
|
|
} else if(isspace(*src)||(*src=='=')){
|
|
|
|
US.state=STATE_TAG_IS;
|
|
|
|
*US.p=0;
|
|
|
|
US.attr=erealloc(US.attr,US.l);
|
|
|
|
} else if(*src=='>') {
|
|
|
|
US.state=STATE_NORMAL;
|
|
|
|
} else {
|
|
|
|
efree(US.attr);
|
|
|
|
US.attr=NULL;
|
|
|
|
US.state=STATE_IN_TAG;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case STATE_TAG_IS:
|
|
|
|
case STATE_TAG_IS2:
|
2000-08-03 11:42:39 +00:00
|
|
|
if(*src=='>'){
|
|
|
|
US.state=STATE_NORMAL;
|
|
|
|
if(! (US.attr_done)) {
|
|
|
|
char *p;
|
|
|
|
p=url_attr_addon(US.tag,US.attr,"",data);
|
|
|
|
if(p) {
|
|
|
|
int l= strlen(p);
|
|
|
|
maxl+=l;
|
|
|
|
out=realloc(out,maxl);
|
|
|
|
outp=out+*newlen;
|
|
|
|
strcpy(outp,p);
|
|
|
|
outp+=l;
|
|
|
|
*newlen+=l;
|
|
|
|
efree(p);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if(*src=='#') {
|
|
|
|
if(! (US.attr_done)) {
|
|
|
|
char *p;
|
|
|
|
US.attr_done=1;
|
|
|
|
p=url_attr_addon(US.tag,US.attr,"#",data);
|
|
|
|
if(p) {
|
|
|
|
int l= strlen(p);
|
|
|
|
maxl+=l;
|
|
|
|
out=realloc(out,maxl);
|
|
|
|
outp=out+*newlen;
|
|
|
|
strcpy(outp,p);
|
|
|
|
outp+=l;
|
|
|
|
*newlen+=l;
|
|
|
|
efree(p);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if(!isspace(*src)&&(*src!='=')) {
|
2000-08-01 07:45:14 +00:00
|
|
|
US.ml=BUFSIZE;
|
|
|
|
US.p=US.val=erealloc(US.val,US.ml);
|
|
|
|
US.l=0;
|
2000-08-03 11:42:39 +00:00
|
|
|
US.attr_done=0;
|
2000-08-01 07:45:14 +00:00
|
|
|
if((*src=='"')||(*src=='\'')) {
|
|
|
|
US.state=STATE_TAG_QVAL2;
|
|
|
|
US.delim=*src;
|
|
|
|
} else {
|
|
|
|
US.state=STATE_TAG_VAL;
|
|
|
|
*US.p++=*src;
|
|
|
|
US.l++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
1999-09-11 23:47:16 +00:00
|
|
|
|
|
|
|
|
2000-08-01 07:45:14 +00:00
|
|
|
case STATE_TAG_QVAL2:
|
2000-08-03 11:42:39 +00:00
|
|
|
if(*src=='#') {
|
|
|
|
if(! (US.attr_done)) {
|
|
|
|
char *p;
|
|
|
|
US.attr_done=1;
|
|
|
|
*US.p='\0';
|
|
|
|
p=url_attr_addon(US.tag,US.attr,US.val,data);
|
|
|
|
if(p) {
|
|
|
|
int l= strlen(p);
|
|
|
|
maxl+=l;
|
|
|
|
out=realloc(out,maxl);
|
|
|
|
outp=out+*newlen;
|
|
|
|
strcpy(outp,p);
|
|
|
|
outp+=l;
|
|
|
|
*newlen+=l;
|
|
|
|
efree(p);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if(*src==US.delim) {
|
2000-08-01 07:45:14 +00:00
|
|
|
US.state=STATE_IN_TAG;
|
|
|
|
*US.p='\0';
|
2000-08-03 11:42:39 +00:00
|
|
|
if(! (US.attr_done)) {
|
|
|
|
char *p;
|
|
|
|
p=url_attr_addon(US.tag,US.attr,US.val,data);
|
|
|
|
if(p) {
|
|
|
|
int l= strlen(p);
|
|
|
|
maxl+=l;
|
|
|
|
out=realloc(out,maxl);
|
|
|
|
outp=out+*newlen;
|
|
|
|
strcpy(outp,p);
|
|
|
|
outp+=l;
|
|
|
|
*newlen+=l;
|
|
|
|
efree(p);
|
|
|
|
}
|
2000-08-01 07:45:14 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
} else if(*src=='\\') {
|
|
|
|
US.state=STATE_TAG_QVAL2b;
|
|
|
|
} else if (*src=='>') {
|
|
|
|
US.state=STATE_NORMAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
*US.p++=*src;
|
|
|
|
++US.l;
|
|
|
|
if(US.l==US.ml) {
|
|
|
|
US.ml+=BUFSIZE;
|
|
|
|
US.val=erealloc(US.val,US.ml);
|
|
|
|
US.p = US.val+US.l;
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
case STATE_TAG_QVAL2b:
|
|
|
|
US.state=STATE_TAG_QVAL2;
|
|
|
|
*US.p++=*src;
|
|
|
|
++US.l;
|
|
|
|
if(US.l==US.ml) {
|
|
|
|
US.ml+=BUFSIZE;
|
|
|
|
US.val=erealloc(US.val,US.ml);
|
|
|
|
US.p = US.val+US.l;
|
|
|
|
}
|
|
|
|
break;
|
1999-09-11 23:47:16 +00:00
|
|
|
|
2000-08-01 07:45:14 +00:00
|
|
|
case STATE_TAG_VAL:
|
|
|
|
case STATE_TAG_VAL2:
|
2000-08-03 11:42:39 +00:00
|
|
|
if(*src=='#') {
|
|
|
|
if(! (US.attr_done)) {
|
|
|
|
char *p;
|
|
|
|
US.attr_done=1;
|
|
|
|
*US.p='\0';
|
|
|
|
p=url_attr_addon(US.tag,US.attr,US.val,data);
|
|
|
|
if(p) {
|
|
|
|
int l= strlen(p);
|
|
|
|
maxl+=l;
|
|
|
|
out=realloc(out,maxl);
|
|
|
|
outp=out+*newlen;
|
|
|
|
strcpy(outp,p);
|
|
|
|
outp+=l;
|
|
|
|
*newlen+=l;
|
|
|
|
efree(p);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if(isspace(*src)||(*src=='>')) {
|
2000-08-01 07:45:14 +00:00
|
|
|
US.state=(*src=='>')?STATE_NORMAL:STATE_IN_TAG;
|
|
|
|
*US.p='\0';
|
2000-08-03 11:42:39 +00:00
|
|
|
if(! (US.attr_done)) {
|
|
|
|
char *p;
|
|
|
|
p=url_attr_addon(US.tag,US.attr,US.val,data);
|
|
|
|
if(p) {
|
|
|
|
int l= strlen(p);
|
|
|
|
maxl+=l;
|
|
|
|
out=realloc(out,maxl);
|
|
|
|
outp=out+*newlen;
|
|
|
|
strcpy(outp,p);
|
|
|
|
outp+=l;
|
|
|
|
*newlen+=l;
|
|
|
|
efree(p);
|
|
|
|
}
|
2000-08-01 07:45:14 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
*US.p++=*src;
|
|
|
|
US.l++;
|
|
|
|
if(US.l==US.ml) {
|
|
|
|
US.ml+=BUFSIZE;
|
|
|
|
US.val=erealloc(US.val,US.ml);
|
|
|
|
US.p = US.val+US.l;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2002-08-28 06:13:49 +00:00
|
|
|
default:
|
|
|
|
break;
|
2000-08-01 07:45:14 +00:00
|
|
|
}
|
1999-09-11 23:47:16 +00:00
|
|
|
|
2000-08-01 07:45:14 +00:00
|
|
|
*outp++=*src++;
|
|
|
|
*newlen+=1;
|
|
|
|
}
|
|
|
|
*outp='\0';
|
|
|
|
return out;
|
1999-09-11 23:47:16 +00:00
|
|
|
}
|
2001-06-06 13:06:12 +00:00
|
|
|
/* }}} */
|
2001-06-05 13:12:10 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Local variables:
|
|
|
|
* tab-width: 4
|
|
|
|
* c-basic-offset: 4
|
|
|
|
* End:
|
2001-09-09 13:29:31 +00:00
|
|
|
* vim600: sw=4 ts=4 fdm=marker
|
|
|
|
* vim<600: sw=4 ts=4
|
2001-06-05 13:12:10 +00:00
|
|
|
*/
|