Exemple #1
0
void TGielda::Refresh_data_onet()
{
	/* FIXME: jesli spolka, umarla ( jej cena to --- ) to nie zostanie
	 * to sparsowane poprawnie i pominieta zostanie kolejna spolka
	 * now blad - onet chyba teraz pokazuje cene w "[]", trzeba poprawic regexp
	 */
	char* bufor = NULL;
	pcre* re;
	const char* error = NULL;
	int erroffset;
	int index = 0;
	int rc;
	const int OVECCOUNT = 30;
	int ovector[OVECCOUNT];
	char* pozycja;

	bufor = Download_file(curl, "http://gielda.onet.pl/indeksy-i-akcje,18633,100,0,notowania-gpw-start");
	my_companies.clear();
	my_companies.reserve(512);
	do
	{
		re = pcre_compile("<div class=\"name2\"><a.*?>(.*?)<.*?raitings.*?>\\s*?\\[?([-0-9, ]+)\\]?\\s*?<.*?raitings.*?>\\s*?\\[?([-0-9,]+)\\]?\\s*?<",
		PCRE_DOTALL, &error, &erroffset, NULL);
		rc = pcre_exec(re, NULL, bufor + index, strlen(bufor + index), 0, 0, ovector,
			OVECCOUNT);
		if (rc == PCRE_ERROR_NOMATCH)
			break;
		if (rc < 0)
			break;
		if (rc == 0)
			puts("za malo miejsca w buforze");
		
		char* name;
		char* price;
		char* day_delta;
		pcre_get_substring(bufor + index, ovector, rc, 1, (const char** )&name);
		pcre_get_substring(bufor + index, ovector, rc, 2, (const char** )&price);
		pcre_get_substring(bufor + index, ovector, rc, 3, (const char** )&day_delta);
		
		if ((pozycja = strchr(day_delta, ',')))
			*pozycja = '.';
		if ((pozycja = strchr(price, ',')))
			*pozycja = '.';
		char* price_replaced = Replace_all(price, " ", "");
		
		TSpolka spolka(name,
			price_replaced ? price_replaced : price,
			day_delta, "", "", "", "", "");
		my_companies.push_back(spolka);

		pcre_free_substring(name);
		pcre_free_substring(price);
		pcre_free_substring(day_delta);

		 index += ovector[1];
	}
	while (true);
	my_last_update = time(NULL);
	delete[] bufor;
}
Exemple #2
0
void TGielda::Refresh_data()
{
	char* bufor = NULL;
	pcre* re;
	const char* error = NULL;
	int erroffset;
	int index = 0;
	int rc;
	const int OVECCOUNT = 30;
	int ovector[OVECCOUNT];
	char* pozycja;

	bufor = Download_file(curl, "http://www.parkiet.com/temat/63.html");
	if (!bufor)
		return;

	my_companies.clear();
	my_companies.reserve(512);
	do
	{
		re = pcre_compile("<tr.*?<td class=\"nazwa\"><a.*?>(.*?)<.*?<td class=\"c\">(.*?)<.*?<td class=\"zmiana.*?>(.*?)<",
		PCRE_DOTALL, &error, &erroffset, NULL);
		rc = pcre_exec(re, NULL, bufor + index, strlen(bufor + index), 0, 0, ovector,
			OVECCOUNT);
		if (rc == PCRE_ERROR_NOMATCH)
			break;
		if (rc < 0)
			break;
		if (rc == 0)
			puts("za malo miejsca w buforze");
		
		char* name;
		char* price;
		char* day_delta;
		pcre_get_substring(bufor + index, ovector, rc, 1, (const char** )&name);
		pcre_get_substring(bufor + index, ovector, rc, 2, (const char** )&price);
		pcre_get_substring(bufor + index, ovector, rc, 3, (const char** )&day_delta);
		
		if ((pozycja = strchr(day_delta, ',')))
			*pozycja = '.';
		TSpolka spolka(name, price, day_delta, "", "", "", "", "");
		my_companies.push_back(spolka);

		pcre_free_substring(name);
		pcre_free_substring(price);
		pcre_free_substring(day_delta);

		 index += ovector[1];
	}
	while (true);
	my_last_update = time(NULL);
	delete[] bufor;
}
Exemple #3
0
// < 0 for error.  >= 0 for len of extracted string
int extractHTTPClientHeaderVal(const u_int8_t *buf, u_int32_t size, int pcreidx, int substringnum, char *valuebuf, int valuelen) {
   int result;
   int ovector[9];
   int ovecsize = 9;
   const char *tmpstring;

//   printf("Searching for pcre %d (%s)\n", pcreidx, http_pcre_strings[pcreidx]);

   result = pcre_exec(http_pcre_structs[pcreidx].re, http_pcre_structs[pcreidx].pe,
                      (const char *)buf, size, 0, 0, ovector, ovecsize);

   if(result < 0 || result == PCRE_ERROR_NOMATCH) {
//      printf("pcre not found\n");
      return(-1); // We need to find the URL or this isn't a valid request
   }

   if(valuebuf) {
      result = pcre_get_substring((const char *)buf, ovector, result, substringnum, &tmpstring);
      if(result < 0) {
//         printf("unable to extract substring\n");
         return(-2);
      }

      strncpy(valuebuf, tmpstring, valuelen);
      valuebuf[valuelen-1] = '\0';

      pcre_free_substring(tmpstring);
      return(strlen(valuebuf));
   }

   return(0);
}
Exemple #4
0
static uint32_t nvmRegExpCoproTestPattern (uint16_t pattern_id, uint8_t *haystack, uint32_t haylen,
							uint32_t start_offset, nvmRegExpCoproInternalData *redata) {
	nvmRegExpCoproPattern *rcp;
	int ovector[OVECTSIZE], m  = 0, matchoffset = 0; //, matchlen = 0;
#ifdef COPRO_REGEXP_DEBUG
			const char *tmp;
#endif
	redata -> matched = 0;

	/* Do the actual search */
	if (pattern_id < redata -> patterns_no) {
		rcp = &(redata -> patterns[pattern_id]);
		redebug ("Looking for RegExp: \"%s\"\n", rcp -> pattern);
		m = pcre_exec (rcp -> re, rcp -> re_extra, (char*) haystack + start_offset, haylen, 0, 0, ovector, OVECTSIZE);
		if (m > 0) {
			(redata -> match).rcp = rcp;
			(redata -> match).offset = matchoffset = ovector[0];
			(redata -> match).len = ovector[1] - ovector[0];
			redata -> matched = 1;
#ifdef COPRO_REGEXP_DEBUG
			pcre_get_substring (haystack + start_offset, ovector, m, 0, &tmp);
			redebug ("RegExp match at offset %d, len = %d: \"%s\"\n", matchoffset, (redata -> match).len, tmp);
			pcre_free_substring (tmp);
#endif
		}
	} else {
		printf ("RegExp coprocessor: tried to use inexistent pattern: %u\n", pattern_id);
	}

	return (redata -> matched);
}
Exemple #5
0
char *execute_regex(char *pattern, char *subject, int desired_match)
{
    pcre *re;
    const char *einfo;
    int eoffset;
    int stringcount = 0;
    int ovector[desired_match * 3];
    int match_len;
    const char *match;
    char *match_returned;
    re = pcre_compile(pattern, 0, &einfo, &eoffset, NULL);
    if (!re) {
	fprintf(stderr, "%s\n", einfo);
	return NULL;
    }

    stringcount = pcre_exec(re, NULL, subject, strlen(subject),
			    0, 0, ovector, 30);

    match_len = pcre_get_substring(subject, ovector,
				   stringcount, desired_match, &match);
    if (match_len <= 0) {

	return NULL;
    }

    match_returned = (char *) malloc(match_len);
    strncpy(match_returned, match, match_len);
    pcre_free_substring(match);
    return match_returned;

}
Exemple #6
0
std::string Pattern::group (int groupNumber)
{
    const char * stringPtr;

    int rc = pcre_get_substring (
                 _subject.substr (_offset[0]).c_str(),
                 _ovector,
                 _count,
                 groupNumber,
                 &stringPtr);

    if (rc < 0) {
        switch (rc) {

            case PCRE_ERROR_NOSUBSTRING:
                throw std::out_of_range ("Invalid group reference.");

            case PCRE_ERROR_NOMEMORY:
                throw match_error ("Memory exhausted.");

            default:
                throw match_error ("Failed to get named substring.");
        }
    }

    std::string matchedStr (stringPtr);

    pcre_free_substring (stringPtr);

    return matchedStr;
}
Exemple #7
0
DeprecatedString RegularExpression::cap(int n) const
{
    const pcre_char *substring = NULL;
    int substringLength = pcre_get_substring(reinterpret_cast<const uint16_t *>(d->lastMatchString.unicode()), d->lastMatchOffsets, d->lastMatchCount, n, &substring);
    if (substringLength > 0) {
       DeprecatedString capture(reinterpret_cast<const DeprecatedChar *>(substring), substringLength);
       pcre_free_substring(substring);
       return capture;
    }
    return DeprecatedString();
}
Exemple #8
0
int matcher_append(char * str) {
    int str_sz = strlen(str), exec_res;
    int groups[60], max_group = 60;
    
    if (str_sz > MBUF) {
        return -1;
    }
  
    if (str_sz + buff_offset >= MBUF) {
        strcpy(buff, str);
        buff_offset = 0;
    } else {
        strcpy(buff + buff_offset, str);
    }
    //printf("matcher: appending [%s]\n\n\n", str);

    exec_res = pcre_exec(regex, regex_opti, buff, buff_offset + str_sz, last_match, 0, groups, max_group);
    if (exec_res == PCRE_ERROR_NOMATCH) {
        puts(buff);
    }
    /*switch(exec_res) {
        case PCRE_ERROR_NOMATCH      : printf("String did not match the pattern\n");        break;
        case PCRE_ERROR_NULL         : printf("Something was null\n");                      break;
        case PCRE_ERROR_BADOPTION    : printf("A bad option was passed\n");                 break;
        case PCRE_ERROR_BADMAGIC     : printf("Magic number bad (compiled re corrupt?)\n"); break;
        case PCRE_ERROR_UNKNOWN_NODE : printf("Something kooky in the compiled re\n");      break;
        case PCRE_ERROR_NOMEMORY     : printf("Ran out of memory\n");                       break;
        default                      : printf("Unknown error\n");                           break;
    }*/
    if (exec_res >= 0) {
        int c;
        const char * match;
        exec_res = exec_res ? exec_res : max_group / 3;
        for (c = 0; c < exec_res; c += 2) {
            //if (c == 0 || c % 3 == 0) continue;
            pcre_get_substring(buff/* + offset ?*/, groups, exec_res, c, &match);
            //printf("Match(%2d/%2d): (%2d,%2d): '%s'\n", c, exec_res-1, groups[c*2], groups[c*2+1], match);
            callback(match);
            pcre_free_substring(match);
            last_match = c * 2 + 1;
        }
    } else {
        last_match = buff_offset;
    }

    //puts(buff);
    //printf("matcher: buff [%s]\n\n", buff);
    buff_offset = (buff_offset + str_sz) - last_match;
    memmove(buff, buff + last_match, buff_offset);
    buff[buff_offset] = '\0';
    
    return 0;
}
static void
free_invalidate_t(invalidate_t *i)
{
  if (i->regex_extra)
#ifndef PCRE_STUDY_JIT_COMPILE
    pcre_free(i->regex_extra);
#else
    pcre_free_study(i->regex_extra);
#endif
  if (i->regex)
    pcre_free(i->regex);
  if (i->regex_text)
    pcre_free_substring(i->regex_text);
  TSfree(i);
}
SWITCH_DECLARE(void) switch_capture_regex(switch_regex_t *re, int match_count, const char *field_data, 
										  int *ovector, const char *var, switch_cap_callback_t callback, void *user_data)
										  
{


	const char *replace;
	int i;

	for (i = 0; i < match_count; i++) {
		if (pcre_get_substring(field_data, ovector, match_count, i, &replace) > 0) {
			callback(var, replace, user_data);
			pcre_free_substring(replace);
		}
	}
}
Exemple #11
0
void format(char* s, const char* fmt, const char* p, int* v, int n)
{
	const char* t = fmt;
	while (1) {
		int c = (int)strcspn(t, ESCAPE_STR);
		memcpy(s, t, c);
		s += c;
		t += c;
		if (!*t) {
			break;
		} else if (*t == ESCAPE_CHAR) {
			if (isdigit(*++t)) {	/* \N */
				c = (*t-'0') * 2;
				++t;
				memcpy(s, p+v[c], v[c+1]-v[c]);
				s += v[c+1] - v[c];
			} else if (isalpha(*t) && isdigit(*(t+1))) {
								/* \xN */
				const char* q;
				++t;
				c = *t - '0';
				if (pcre_get_substring(p, v, n, c, &q) <= 0) {
					++t;
					/* TODO: handle error */
					continue;
				}
				if (find_translation(q, s,
							to_section(*(t-1)))) {
					s += strlen(s);
				} else {
					s += pcre_copy_substring(p, v, n, c, s,
							100);
					/* TODO: fix the use of magic number */
				}
				++t;
				pcre_free_substring(q);
			} else {
				++t;
				/* do nothing */
			}
		} else {
			printf("\nformat: impossible!\n");
			system("pause");
		}
	}
	*s = 0;
}
/**
 * \brief This function is used to parse IPV4 ip_id passed via keyword: "id"
 *
 * \param idstr Pointer to the user provided id option
 *
 * \retval id_d pointer to DetectSshSoftwareVersionData on success
 * \retval NULL on failure
 */
DetectSshSoftwareVersionData *DetectSshSoftwareVersionParse (char *str)
{
    DetectSshSoftwareVersionData *ssh = NULL;
#define MAX_SUBSTRINGS 30
    int ret = 0, res = 0;
    int ov[MAX_SUBSTRINGS];

    ret = pcre_exec(parse_regex, parse_regex_study, str, strlen(str), 0, 0,
                    ov, MAX_SUBSTRINGS);

    if (ret < 1 || ret > 3) {
        SCLogError(SC_ERR_PCRE_MATCH, "invalid ssh.softwareversion option");
        goto error;
    }

    if (ret > 1) {
        const char *str_ptr = NULL;
        res = pcre_get_substring((char *)str, ov, MAX_SUBSTRINGS, 1, &str_ptr);
        if (res < 0) {
            SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed");
            goto error;
        }

        /* We have a correct id option */
        ssh = SCMalloc(sizeof(DetectSshSoftwareVersionData));
        if (unlikely(ssh == NULL))
            goto error;

        ssh->software_ver = (uint8_t *)SCStrdup((char *)str_ptr);
        if (ssh->software_ver == NULL) {
            goto error;
        }
        pcre_free_substring(str_ptr);

        ssh->len = strlen((char *)ssh->software_ver);

        SCLogDebug("will look for ssh %s", ssh->software_ver);
    }

    return ssh;

error:
    if (ssh != NULL)
        DetectSshSoftwareVersionFree(ssh);
    return NULL;

}
SWITCH_DECLARE(void) switch_perform_substitution(switch_regex_t *re, int match_count, const char *data, const char *field_data,
												 char *substituted, switch_size_t len, int *ovector)
{
	char index[10] = "";
	const char *replace = NULL;
	switch_size_t x, y = 0, z = 0;
	int num = 0;

	for (x = 0; x < (len - 1) && x < strlen(data);) {
		if (data[x] == '$') {
			x++;

			if (!(data[x] > 47 && data[x] < 58)) {
				substituted[y++] = data[x - 1];
				continue;
			}

			while (data[x] > 47 && data[x] < 58) {
				index[z++] = data[x];
				x++;
			}
			index[z++] = '\0';
			z = 0;
			num = atoi(index);

			if (num < 0 || num > 256) {
				num = -1;
			}

			if (pcre_get_substring(field_data, ovector, match_count, num, &replace) > 0) {
				switch_size_t r;
				for (r = 0; r < strlen(replace); r++) {
					substituted[y++] = replace[r];
				}
				pcre_free_substring(replace);
			}
		} else {
			substituted[y++] = data[x];
			x++;
		}
	}
	substituted[y++] = '\0';
}
Exemple #14
0
int check_regexp_match(const char *str, const char *pattern)
{
	int options = PCRE_UTF8;
	const char *error;
	int erroffset;

	const unsigned char *tables = pcre_maketables();
	pcre *re = pcre_compile(pattern, options, &error, &erroffset, tables);
	if (!re)
	{
		log_message(ERROR, _("Can't compile regular expression '%s'"), pattern);
		return FALSE;
	}

	int str_len = strlen(str);

	int ovector[50];
	int count = pcre_exec(re, NULL, str, str_len, 0, 0, ovector, 50);
	if (count <= 0 && count != PCRE_ERROR_NOMATCH)
	{
		log_message(ERROR, _("Can't exec regular expression '%s', eror code %d"), pattern, count);
		pcre_free(re);
		pcre_free((void*)tables);
		return FALSE;
	}

	pcre_free(re);
	pcre_free((void*)tables);
	
	if (count == PCRE_ERROR_NOMATCH)
		return FALSE;
	
	const char *pcre_string = NULL;
	if(pcre_get_substring(str, ovector, count, 0, &pcre_string) < 0)
		return FALSE;

	//log_message(TRACE, _("Match word '%s' and PERL pattern '%s'"), str, pattern);
	
	pcre_free_substring(pcre_string);
		
	return TRUE;
}
Exemple #15
0
std::string Pattern::group (const std::string& groupName)
{
    const char * stringPtr = NULL;

    int rc = pcre_get_named_substring (
                 _re,
                 _subject.substr (_offset[0]).c_str(),
                 _ovector,
                 _count,
                 groupName.c_str(),
                 &stringPtr);

    if (rc < 0) {
        switch (rc) {

            case PCRE_ERROR_NOSUBSTRING:

                break;

            case PCRE_ERROR_NOMEMORY:
                throw match_error ("Memory exhausted.");

            default:
                throw match_error ("Failed to get named substring.");
        }
    }

    std::string matchedStr;

    if (stringPtr) {

        matchedStr = stringPtr;
        pcre_free_substring (stringPtr);
    } else {

        matchedStr = "";
    }

    return matchedStr;

}
// custom callback function to exec on each match
void pcre_match_callback(PCRE_CONTAINER *pcre_info)
{
  // get_named_substring if it exists
  if(pcre_info->namecount > 0)
  {
    const char *matched_substring = NULL;

    if((fetch_named_substring(pcre_info->named_substring, pcre_info, &matched_substring)) >= 0)
    {
      char *ret = NULL;
      if((ret=str_replace("\\u0026#39;","\'",(char*)matched_substring)))
      {
        printf("substring match for %s: %s\n",pcre_info->named_substring,ret);
        free(ret);
      } else {
        printf("substring match for %s: %s\n",pcre_info->named_substring,matched_substring);
      }
      pcre_free_substring(matched_substring);
    }
  }
}
int main(int argc, char *argv[]) {
  pcre *reCompiled;
  pcre_extra *pcreExtra;
  int pcreExecRet;
  int subStrVec[30];
  const char *pcreErrorStr;
  int pcreErrorOffset;
  char *aStrRegex;
  char **aLineToMatch;
  const char *psubStrMatchStr;
  int j;
  char *testStrings[] = { "This should match... hello",
                          "This could match... hello!",
                          "More than one hello.. hello",
                          "No chance of a match...",
                          NULL};


  printf("lscan test binary file statically compiled with libpcre-8.37\n");

  aStrRegex = "(.*)(hello)+";  
  printf("Regex to use: %s\n", aStrRegex);

  // First, the regex string must be compiled.
  reCompiled = pcre_compile(aStrRegex, 0, &pcreErrorStr, &pcreErrorOffset, NULL);

  /* OPTIONS (second argument) (||'ed together) can be:
       PCRE_ANCHORED       -- Like adding ^ at start of pattern.
       PCRE_CASELESS       -- Like m//i
       PCRE_DOLLAR_ENDONLY -- Make $ match end of string regardless of \n's
                              No Perl equivalent.
       PCRE_DOTALL         -- Makes . match newlins too.  Like m//s
       PCRE_EXTENDED       -- Like m//x
       PCRE_EXTRA          -- 
       PCRE_MULTILINE      -- Like m//m
       PCRE_UNGREEDY       -- Set quantifiers to be ungreedy.  Individual quantifiers
                              may be set to be greedy if they are followed by "?".
       PCRE_UTF8           -- Work with UTF8 strings.
  */

  // pcre_compile returns NULL on error, and sets pcreErrorOffset & pcreErrorStr
  if(reCompiled == NULL) {
    printf("ERROR: Could not compile '%s': %s\n", aStrRegex, pcreErrorStr);
    exit(1);
  } /* end if */

  // Optimize the regex
  pcreExtra = pcre_study(reCompiled, 0, &pcreErrorStr);

  /* pcre_study() returns NULL for both errors and when it can not optimize the regex.  The last argument is how one checks for
     errors (it is NULL if everything works, and points to an error string otherwise. */
  if(pcreErrorStr != NULL) {
    printf("ERROR: Could not study '%s': %s\n", aStrRegex, pcreErrorStr);
    exit(1);
  } /* end if */

  for(aLineToMatch=testStrings; *aLineToMatch != NULL; aLineToMatch++) {
    printf("String: %s\n", *aLineToMatch);
    printf("        %s\n", "0123456789012345678901234567890123456789");
    printf("        %s\n", "0         1         2         3");

    /* Try to find the regex in aLineToMatch, and report results. */
    pcreExecRet = pcre_exec(reCompiled,
                            pcreExtra,
                            *aLineToMatch, 
                            strlen(*aLineToMatch),  // length of string
                            0,                      // Start looking at this point
                            0,                      // OPTIONS
                            subStrVec,
                            30);                    // Length of subStrVec

    /* pcre_exec OPTIONS (||'ed together) can be:
       PCRE_ANCHORED -- can be turned on at this time.
       PCRE_NOTBOL
       PCRE_NOTEOL
       PCRE_NOTEMPTY */

    // Report what happened in the pcre_exec call..
    //printf("pcre_exec return: %d\n", pcreExecRet);
    if(pcreExecRet < 0) { // Something bad happened..
      switch(pcreExecRet) {
      case PCRE_ERROR_NOMATCH      : printf("String did not match the pattern\n");        break;
      case PCRE_ERROR_NULL         : printf("Something was null\n");                      break;
      case PCRE_ERROR_BADOPTION    : printf("A bad option was passed\n");                 break;
      case PCRE_ERROR_BADMAGIC     : printf("Magic number bad (compiled re corrupt?)\n"); break;
      case PCRE_ERROR_UNKNOWN_NODE : printf("Something kooky in the compiled re\n");      break;
      case PCRE_ERROR_NOMEMORY     : printf("Ran out of memory\n");                       break;
      default                      : printf("Unknown error\n");                           break;
      } /* end switch */
    } else {
      printf("Result: We have a match!\n");
        
      // At this point, rc contains the number of substring matches found...
      if(pcreExecRet == 0) {
        printf("But too many substrings were found to fit in subStrVec!\n");
        // Set rc to the max number of substring matches possible.
        pcreExecRet = 30 / 3;
      } /* end if */

      // Do it yourself way to get the first substring match (whole pattern):
      // char subStrMatchStr[1024];
      // int i, j
      // for(j=0,i=subStrVec[0];i<subStrVec[1];i++,j++) 
      //   subStrMatchStr[j] = (*aLineToMatch)[i];
      // subStrMatchStr[subStrVec[1]-subStrVec[0]] = 0;
      //printf("MATCHED SUBSTRING: '%s'\n", subStrMatchStr);
        
      // PCRE contains a handy function to do the above for you:
      for(j=0; j<pcreExecRet; j++) {
        pcre_get_substring(*aLineToMatch, subStrVec, pcreExecRet, j, &(psubStrMatchStr));
        printf("Match(%2d/%2d): (%2d,%2d): '%s'\n", j, pcreExecRet-1, subStrVec[j*2], subStrVec[j*2+1], psubStrMatchStr);
      } /* end for */
        
      // Free up the substring
      pcre_free_substring(psubStrMatchStr);
    }  /* end if/else */
    printf("\n");
      
  } /* end for */
  
  // Free up the regular expression.
  pcre_free(reCompiled);
      
  // Free up the EXTRA PCRE value (may be NULL at this point)
  if(pcreExtra != NULL)
    pcre_free(pcreExtra);

  // We are all done..
  return 0;

} /* end func main */
Exemple #18
0
int
parse_file(char *path, char **data_head, char **data_tail, char **data,
	   int *data_size)
{
    FILE *fp;
    long fz;
    char *buf;

    pcre *re;
    const char *einfo;
    int eoffset;
    int stringcount = 0;
    int ovector[30];
    const char *head = NULL;
    const char *tail = NULL;
    const char *fdata = NULL;
    int head_size, tail_size;
    int datastart, dataend, datalength;

    /*
     * open the file and read the whole thing... 
     */

    fp = fopen(path, "r");
    if (!fp) {
	fprintf(stderr, "Couldn't open file!\n");
	return 0;
    }
    fseek(fp, 0L, SEEK_END);
    fz = ftell(fp);

    fseek(fp, 0L, SEEK_SET);
    buf = (char *) malloc(fz);

    fread(buf, 1, fz, fp);

    /* try to find the two ranges we need */
    re = pcre_compile("(=ybegin[^\r\n]+).+(=yend[^\r\n]+)",
		      (PCRE_CASELESS | PCRE_DOTALL | PCRE_MULTILINE |
		       PCRE_NEWLINE_ANYCRLF), &einfo, &eoffset, NULL);


    if (!re) {
	fprintf(stderr, "%s\n", einfo);
	return 0;
    }

    stringcount = pcre_exec(re, NULL, buf, fz, 0, 0, ovector, 30);


    head_size = pcre_get_substring(buf, ovector, stringcount, 1, &head);
    tail_size = pcre_get_substring(buf, ovector, stringcount, 2, &tail);
    fprintf(stderr, "Head Size: %d, Tail Size: %d\n", head_size,
	    tail_size);

    *data_head = malloc(head_size);
    strncpy(*data_head, head, head_size);

    *data_tail = malloc(tail_size);
    strncpy(*data_tail, tail, tail_size);

    if (!data_head || !data_tail) {
	fprintf(stderr, "Not a yenc file!\n");
	return 0;
    }
    datastart = ovector[3] + 1;
    dataend = ovector[4] - 1;
    datalength = dataend - datastart;
    *data_size = datalength;

    *data = malloc(datalength);
    strncpy(*data, buf + datastart, datalength);

    free(buf);
    pcre_free_substring(head);
    pcre_free_substring(tail);


    return 1;

}
/**
 * \brief Parses a line from the reference config file and adds it to Reference
 *        Config hash table DetectEngineCtx->reference_conf_ht.
 *
 * \param rawstr Pointer to the string to be parsed.
 * \param de_ctx Pointer to the Detection Engine Context.
 *
 * \retval  0 On success.
 * \retval -1 On failure.
 */
static int SCRConfAddReference(char *rawstr, DetectEngineCtx *de_ctx)
{
    const char *system = NULL;
    const char *url = NULL;

    SCRConfReference *ref_new = NULL;
    SCRConfReference *ref_lookup = NULL;

#define MAX_SUBSTRINGS 30
    int ret = 0;
    int ov[MAX_SUBSTRINGS];

    ret = pcre_exec(regex, regex_study, rawstr, strlen(rawstr), 0, 0, ov, 30);
    if (ret < 0) {
        SCLogError(SC_ERR_REFERENCE_CONFIG, "Invalid Reference Config in "
                   "reference.config file");
        goto error;
    }

    /* retrieve the reference system */
    ret = pcre_get_substring((char *)rawstr, ov, 30, 1, &system);
    if (ret < 0) {
        SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring() failed");
        goto error;
    }

    /* retrieve the reference url */
    ret = pcre_get_substring((char *)rawstr, ov, 30, 2, &url);
    if (ret < 0) {
        SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring() failed");
        goto error;
    }

    /* Create a new instance of the parsed Reference string */
    ref_new = SCRConfAllocSCRConfReference(system, url);

    /* Check if the Reference is present in the HashTable.  In case it's present
     * ignore it, as it's a duplicate.  If not present, add it to the table */
    ref_lookup = HashTableLookup(de_ctx->reference_conf_ht, ref_new, 0);
    if (ref_lookup == NULL) {
        if (HashTableAdd(de_ctx->reference_conf_ht, ref_new, 0) < 0) {
            SCLogDebug("HashTable Add failed");
        }
    } else {
        SCLogDebug("Duplicate reference found inside reference.config");
        SCRConfDeAllocSCRConfReference(ref_new);
    }

    /* free the substrings */
    pcre_free_substring(system);
    pcre_free_substring(url);
    return 0;

 error:
    if (system)
        pcre_free_substring(system);
    if (url)
        pcre_free_substring(url);

    return -1;
}
Exemple #20
0
/**
 * \brief Parse the arg supplied with ssl_state and return it in a
 *        DetectSslStateData instance.
 *
 * \param arg Pointer to the string to be parsed.
 *
 * \retval ssd  Pointer to DetectSslStateData on succese.
 * \retval NULL On failure.
 */
DetectSslStateData *DetectSslStateParse(char *arg)
{
#define MAX_SUBSTRINGS 30
    int ret = 0, res = 0;
    int ov1[MAX_SUBSTRINGS];
    int ov2[MAX_SUBSTRINGS];
    const char *str1;
    const char *str2;
    int negate = 0;
    uint32_t flags = 0, mask = 0;
    DetectSslStateData *ssd = NULL;

    ret = pcre_exec(parse_regex1, parse_regex1_study, arg, strlen(arg), 0, 0,
                    ov1, MAX_SUBSTRINGS);
    if (ret < 1) {
        SCLogError(SC_ERR_INVALID_SIGNATURE, "Invalid arg \"%s\" supplied to "
                   "ssl_state keyword.", arg);
        goto error;
    }

    res = pcre_get_substring((char *)arg, ov1, MAX_SUBSTRINGS, 1, &str1);
    if (res < 0) {
        SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed");
        goto error;
    }
    negate = !strcmp("!", str1);
    pcre_free_substring(str1);

    res = pcre_get_substring((char *)arg, ov1, MAX_SUBSTRINGS, 2, &str1);
    if (res < 0) {
        SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed");
        goto error;
    }

    if (strcmp("client_hello", str1) == 0) {
        flags |= DETECT_SSL_STATE_CLIENT_HELLO;
        if (negate)
            mask |= DETECT_SSL_STATE_CLIENT_HELLO;
    } else if (strcmp("server_hello", str1) == 0) {
        flags |= DETECT_SSL_STATE_SERVER_HELLO;
        if (negate)
            mask |= DETECT_SSL_STATE_SERVER_HELLO;
    } else if (strcmp("client_keyx", str1) == 0) {
        flags |= DETECT_SSL_STATE_CLIENT_KEYX;
        if (negate)
            mask |= DETECT_SSL_STATE_CLIENT_KEYX;
    } else if (strcmp("server_keyx", str1) == 0) {
        flags |= DETECT_SSL_STATE_SERVER_KEYX;
        if (negate)
            mask |= DETECT_SSL_STATE_SERVER_KEYX;
    } else if (strcmp("unknown", str1) == 0) {
        flags |= DETECT_SSL_STATE_UNKNOWN;
        if (negate)
            mask |= DETECT_SSL_STATE_UNKNOWN;
    } else {
        SCLogError(SC_ERR_INVALID_SIGNATURE, "Found invalid option \"%s\" "
                   "in ssl_state keyword.", str1);
        goto error;
    }

    pcre_free_substring(str1);

    res = pcre_get_substring((char *)arg, ov1, MAX_SUBSTRINGS, 3, &str1);
    if (res < 0) {
        SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed");
        goto error;
    }
    while (res > 0) {
        ret = pcre_exec(parse_regex2, parse_regex2_study, str1, strlen(str1), 0, 0,
                        ov2, MAX_SUBSTRINGS);
        if (ret < 1) {
            SCLogError(SC_ERR_INVALID_SIGNATURE, "Invalid arg \"%s\" supplied to "
                       "ssl_state keyword.", arg);
            goto error;
        }

        res = pcre_get_substring((char *)str1, ov2, MAX_SUBSTRINGS, 1, &str2);
        if (res < 0) {
            SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed");
            goto error;
        }
        negate = !strcmp("!", str2);
        pcre_free_substring(str2);

        res = pcre_get_substring((char *)str1, ov2, MAX_SUBSTRINGS, 2, &str2);
        if (res <= 0) {
            SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed");
            goto error;
        }
        if (strcmp("client_hello", str2) == 0) {
            flags |= DETECT_SSL_STATE_CLIENT_HELLO;
            if (negate)
                mask |= DETECT_SSL_STATE_CLIENT_HELLO;
        } else if (strcmp("server_hello", str2) == 0) {
            flags |= DETECT_SSL_STATE_SERVER_HELLO;
            if (negate)
                mask |= DETECT_SSL_STATE_SERVER_HELLO;
        } else if (strcmp("client_keyx", str2) == 0) {
            flags |= DETECT_SSL_STATE_CLIENT_KEYX;
            if (negate)
                mask |= DETECT_SSL_STATE_CLIENT_KEYX;
        } else if (strcmp("server_keyx", str2) == 0) {
            flags |= DETECT_SSL_STATE_SERVER_KEYX;
            if (negate)
                mask |= DETECT_SSL_STATE_SERVER_KEYX;
        } else if (strcmp("unknown", str2) == 0) {
            flags |= DETECT_SSL_STATE_UNKNOWN;
            if (negate)
                mask |= DETECT_SSL_STATE_UNKNOWN;
        } else {
            SCLogError(SC_ERR_INVALID_SIGNATURE, "Found invalid option \"%s\" "
                       "in ssl_state keyword.", str2);
            goto error;
        }

        res = pcre_get_substring((char *)str1, ov2, MAX_SUBSTRINGS, 3, &str2);
        if (res < 0) {
            SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed");
            goto error;
        }

        pcre_free_substring(str1);
        str1 = str2;
    }
    pcre_free_substring(str1);

    if ( (ssd = SCMalloc(sizeof(DetectSslStateData))) == NULL) {
        goto error;
    }
    ssd->flags = flags;
    ssd->mask = mask;

    return ssd;

error:
    if (ssd != NULL)
        DetectSslStateFree(ssd);
    return NULL;
}
Exemple #21
0
int main(int argc, char **argv)
{
FILE *infile = stdin;
int options = 0;
int study_options = 0;
int op = 1;
int timeit = 0;
int showinfo = 0;
int showstore = 0;
int size_offsets = 45;
int size_offsets_max;
int *offsets;
#if !defined NOPOSIX
int posix = 0;
#endif
int debug = 0;
int done = 0;
unsigned char buffer[30000];
unsigned char dbuffer[1024];

/* Static so that new_malloc can use it. */

outfile = stdout;

/* Scan options */

while (argc > 1 && argv[op][0] == '-')
  {
  char *endptr;

  if (strcmp(argv[op], "-s") == 0 || strcmp(argv[op], "-m") == 0)
    showstore = 1;
  else if (strcmp(argv[op], "-t") == 0) timeit = 1;
  else if (strcmp(argv[op], "-i") == 0) showinfo = 1;
  else if (strcmp(argv[op], "-d") == 0) showinfo = debug = 1;
  else if (strcmp(argv[op], "-o") == 0 && argc > 2 &&
      ((size_offsets = (int)strtoul(argv[op+1], &endptr, 10)), *endptr == 0))
    {
    op++;
    argc--;
    }
#if !defined NOPOSIX
  else if (strcmp(argv[op], "-p") == 0) posix = 1;
#endif
  else
    {
    printf("** Unknown or malformed option %s\n", argv[op]);
    printf("Usage:   pcretest [-d] [-i] [-o <n>] [-p] [-s] [-t] [<input> [<output>]]\n");
    printf("  -d     debug: show compiled code; implies -i\n"
           "  -i     show information about compiled pattern\n"
           "  -o <n> set size of offsets vector to <n>\n");
#if !defined NOPOSIX
    printf("  -p     use POSIX interface\n");
#endif
    printf("  -s     output store information\n"
           "  -t     time compilation and execution\n");
    return 1;
    }
  op++;
  argc--;
  }

/* Get the store for the offsets vector, and remember what it was */

size_offsets_max = size_offsets;
offsets = malloc(size_offsets_max * sizeof(int));
if (offsets == NULL)
  {
  printf("** Failed to get %d bytes of memory for offsets vector\n",
    size_offsets_max * sizeof(int));
  return 1;
  }

/* Sort out the input and output files */

if (argc > 1)
  {
  infile = fopen(argv[op], "r");
  if (infile == NULL)
    {
    printf("** Failed to open %s\n", argv[op]);
    return 1;
    }
  }

if (argc > 2)
  {
  outfile = fopen(argv[op+1], "w");
  if (outfile == NULL)
    {
    printf("** Failed to open %s\n", argv[op+1]);
    return 1;
    }
  }

/* Set alternative malloc function */

pcre_malloc = new_malloc;

/* Heading line, then prompt for first regex if stdin */

fprintf(outfile, "PCRE version %s\n\n", pcre_version());

/* Main loop */

while (!done)
  {
  pcre *re = NULL;
  pcre_extra *extra = NULL;

#if !defined NOPOSIX  /* There are still compilers that require no indent */
  regex_t preg;
  int do_posix = 0;
#endif

  const char *error;
  unsigned char *p, *pp, *ppp;
  const unsigned char *tables = NULL;
  int do_study = 0;
  int do_debug = debug;
  int do_G = 0;
  int do_g = 0;
  int do_showinfo = showinfo;
  int do_showrest = 0;
  int utf8 = 0;
  int erroroffset, len, delimiter;

  if (infile == stdin) printf("  re> ");
  if (fgets((char *)buffer, sizeof(buffer), infile) == NULL) break;
  if (infile != stdin) fprintf(outfile, "%s", (char *)buffer);

  p = buffer;
  while (isspace(*p)) p++;
  if (*p == 0) continue;

  /* Get the delimiter and seek the end of the pattern; if is isn't
  complete, read more. */

  delimiter = *p++;

  if (isalnum(delimiter) || delimiter == '\\')
    {
    fprintf(outfile, "** Delimiter must not be alphameric or \\\n");
    goto SKIP_DATA;
    }

  pp = p;

  for(;;)
    {
    while (*pp != 0)
      {
      if (*pp == '\\' && pp[1] != 0) pp++;
        else if (*pp == delimiter) break;
      pp++;
      }
    if (*pp != 0) break;

    len = sizeof(buffer) - (pp - buffer);
    if (len < 256)
      {
      fprintf(outfile, "** Expression too long - missing delimiter?\n");
      goto SKIP_DATA;
      }

    if (infile == stdin) printf("    > ");
    if (fgets((char *)pp, len, infile) == NULL)
      {
      fprintf(outfile, "** Unexpected EOF\n");
      done = 1;
      goto CONTINUE;
      }
    if (infile != stdin) fprintf(outfile, "%s", (char *)pp);
    }

  /* If the first character after the delimiter is backslash, make
  the pattern end with backslash. This is purely to provide a way
  of testing for the error message when a pattern ends with backslash. */

  if (pp[1] == '\\') *pp++ = '\\';

  /* Terminate the pattern at the delimiter */

  *pp++ = 0;

  /* Look for options after final delimiter */

  options = 0;
  study_options = 0;
  log_store = showstore;  /* default from command line */

  while (*pp != 0)
    {
    switch (*pp++)
      {
      case 'g': do_g = 1; break;
      case 'i': options |= PCRE_CASELESS; break;
      case 'm': options |= PCRE_MULTILINE; break;
      case 's': options |= PCRE_DOTALL; break;
      case 'x': options |= PCRE_EXTENDED; break;

      case '+': do_showrest = 1; break;
      case 'A': options |= PCRE_ANCHORED; break;
      case 'D': do_debug = do_showinfo = 1; break;
      case 'E': options |= PCRE_DOLLAR_ENDONLY; break;
      case 'G': do_G = 1; break;
      case 'I': do_showinfo = 1; break;
      case 'M': log_store = 1; break;

#if !defined NOPOSIX
      case 'P': do_posix = 1; break;
#endif

      case 'S': do_study = 1; break;
      case 'U': options |= PCRE_UNGREEDY; break;
      case 'X': options |= PCRE_EXTRA; break;
      case '8': options |= PCRE_UTF8; utf8 = 1; break;

      case 'L':
      ppp = pp;
      while (*ppp != '\n' && *ppp != ' ') ppp++;
      *ppp = 0;
      if (setlocale(LC_CTYPE, (const char *)pp) == NULL)
        {
        fprintf(outfile, "** Failed to set locale \"%s\"\n", pp);
        goto SKIP_DATA;
        }
      tables = pcre_maketables();
      pp = ppp;
      break;

      case '\n': case ' ': break;
      default:
      fprintf(outfile, "** Unknown option '%c'\n", pp[-1]);
      goto SKIP_DATA;
      }
    }

  /* Handle compiling via the POSIX interface, which doesn't support the
  timing, showing, or debugging options, nor the ability to pass over
  local character tables. */

#if !defined NOPOSIX
  if (posix || do_posix)
    {
    int rc;
    int cflags = 0;
    if ((options & PCRE_CASELESS) != 0) cflags |= REG_ICASE;
    if ((options & PCRE_MULTILINE) != 0) cflags |= REG_NEWLINE;
    rc = regcomp(&preg, (char *)p, cflags);

    /* Compilation failed; go back for another re, skipping to blank line
    if non-interactive. */

    if (rc != 0)
      {
      (void)regerror(rc, &preg, (char *)buffer, sizeof(buffer));
      fprintf(outfile, "Failed: POSIX code %d: %s\n", rc, buffer);
      goto SKIP_DATA;
      }
    }

  /* Handle compiling via the native interface */

  else
#endif  /* !defined NOPOSIX */

    {
    if (timeit)
      {
      register int i;
      clock_t time_taken;
      clock_t start_time = clock();
      for (i = 0; i < LOOPREPEAT; i++)
        {
        re = pcre_compile((char *)p, options, &error, &erroroffset, tables);
        if (re != NULL) free(re);
        }
      time_taken = clock() - start_time;
      fprintf(outfile, "Compile time %.3f milliseconds\n",
        ((double)time_taken * 1000.0) /
        ((double)LOOPREPEAT * (double)CLOCKS_PER_SEC));
      }

    re = pcre_compile((char *)p, options, &error, &erroroffset, tables);

    /* Compilation failed; go back for another re, skipping to blank line
    if non-interactive. */

    if (re == NULL)
      {
      fprintf(outfile, "Failed: %s at offset %d\n", error, erroroffset);
      SKIP_DATA:
      if (infile != stdin)
        {
        for (;;)
          {
          if (fgets((char *)buffer, sizeof(buffer), infile) == NULL)
            {
            done = 1;
            goto CONTINUE;
            }
          len = (int)strlen((char *)buffer);
          while (len > 0 && isspace(buffer[len-1])) len--;
          if (len == 0) break;
          }
        fprintf(outfile, "\n");
        }
      goto CONTINUE;
      }

    /* Compilation succeeded; print data if required. There are now two
    info-returning functions. The old one has a limited interface and
    returns only limited data. Check that it agrees with the newer one. */

    if (do_showinfo)
      {
      unsigned long int get_options;
      int old_first_char, old_options, old_count;
      int count, backrefmax, first_char, need_char;
      size_t size;

      if (do_debug) print_internals(re);

      new_info(re, NULL, PCRE_INFO_OPTIONS, &get_options);
      new_info(re, NULL, PCRE_INFO_SIZE, &size);
      new_info(re, NULL, PCRE_INFO_CAPTURECOUNT, &count);
      new_info(re, NULL, PCRE_INFO_BACKREFMAX, &backrefmax);
      new_info(re, NULL, PCRE_INFO_FIRSTCHAR, &first_char);
      new_info(re, NULL, PCRE_INFO_LASTLITERAL, &need_char);

      old_count = pcre_info(re, &old_options, &old_first_char);
      if (count < 0) fprintf(outfile,
        "Error %d from pcre_info()\n", count);
      else
        {
        if (old_count != count) fprintf(outfile,
          "Count disagreement: pcre_fullinfo=%d pcre_info=%d\n", count,
            old_count);

        if (old_first_char != first_char) fprintf(outfile,
          "First char disagreement: pcre_fullinfo=%d pcre_info=%d\n",
            first_char, old_first_char);

        if (old_options != (int)get_options) fprintf(outfile,
          "Options disagreement: pcre_fullinfo=%ld pcre_info=%d\n",
            get_options, old_options);
        }

      if (size != gotten_store) fprintf(outfile,
        "Size disagreement: pcre_fullinfo=%d call to malloc for %d\n",
        size, gotten_store);

      fprintf(outfile, "Capturing subpattern count = %d\n", count);
      if (backrefmax > 0)
        fprintf(outfile, "Max back reference = %d\n", backrefmax);
      if (get_options == 0) fprintf(outfile, "No options\n");
        else fprintf(outfile, "Options:%s%s%s%s%s%s%s%s%s\n",
          ((get_options & PCRE_ANCHORED) != 0)? " anchored" : "",
          ((get_options & PCRE_CASELESS) != 0)? " caseless" : "",
          ((get_options & PCRE_EXTENDED) != 0)? " extended" : "",
          ((get_options & PCRE_MULTILINE) != 0)? " multiline" : "",
          ((get_options & PCRE_DOTALL) != 0)? " dotall" : "",
          ((get_options & PCRE_DOLLAR_ENDONLY) != 0)? " dollar_endonly" : "",
          ((get_options & PCRE_EXTRA) != 0)? " extra" : "",
          ((get_options & PCRE_UNGREEDY) != 0)? " ungreedy" : "",
          ((get_options & PCRE_UTF8) != 0)? " utf8" : "");

      if (((((real_pcre *)re)->options) & PCRE_ICHANGED) != 0)
        fprintf(outfile, "Case state changes\n");

      if (first_char == -1)
        {
        fprintf(outfile, "First char at start or follows \\n\n");
        }
      else if (first_char < 0)
        {
        fprintf(outfile, "No first char\n");
        }
      else
        {
        if (isprint(first_char))
          fprintf(outfile, "First char = \'%c\'\n", first_char);
        else
          fprintf(outfile, "First char = %d\n", first_char);
        }

      if (need_char < 0)
        {
        fprintf(outfile, "No need char\n");
        }
      else
        {
        if (isprint(need_char))
          fprintf(outfile, "Need char = \'%c\'\n", need_char);
        else
          fprintf(outfile, "Need char = %d\n", need_char);
        }
      }

    /* If /S was present, study the regexp to generate additional info to
    help with the matching. */

    if (do_study)
      {
      if (timeit)
        {
        register int i;
        clock_t time_taken;
        clock_t start_time = clock();
        for (i = 0; i < LOOPREPEAT; i++)
          extra = pcre_study(re, study_options, &error);
        time_taken = clock() - start_time;
        if (extra != NULL) free(extra);
        fprintf(outfile, "  Study time %.3f milliseconds\n",
          ((double)time_taken * 1000.0)/
          ((double)LOOPREPEAT * (double)CLOCKS_PER_SEC));
        }

      extra = pcre_study(re, study_options, &error);
      if (error != NULL)
        fprintf(outfile, "Failed to study: %s\n", error);
      else if (extra == NULL)
        fprintf(outfile, "Study returned NULL\n");

      else if (do_showinfo)
        {
        uschar *start_bits = NULL;
        new_info(re, extra, PCRE_INFO_FIRSTTABLE, &start_bits);
        if (start_bits == NULL)
          fprintf(outfile, "No starting character set\n");
        else
          {
          int i;
          int c = 24;
          fprintf(outfile, "Starting character set: ");
          for (i = 0; i < 256; i++)
            {
            if ((start_bits[i/8] & (1<<(i%8))) != 0)
              {
              if (c > 75)
                {
                fprintf(outfile, "\n  ");
                c = 2;
                }
              if (isprint(i) && i != ' ')
                {
                fprintf(outfile, "%c ", i);
                c += 2;
                }
              else
                {
                fprintf(outfile, "\\x%02x ", i);
                c += 5;
                }
              }
            }
          fprintf(outfile, "\n");
          }
        }
      }
    }

  /* Read data lines and test them */

  for (;;)
    {
    unsigned char *q;
    unsigned char *bptr = dbuffer;
    int *use_offsets = offsets;
    int use_size_offsets = size_offsets;
    int count, c;
    int copystrings = 0;
    int getstrings = 0;
    int getlist = 0;
    int gmatched = 0;
    int start_offset = 0;
    int g_notempty = 0;

    options = 0;

    if (infile == stdin) printf("data> ");
    if (fgets((char *)buffer, sizeof(buffer), infile) == NULL)
      {
      done = 1;
      goto CONTINUE;
      }
    if (infile != stdin) fprintf(outfile, "%s", (char *)buffer);

    len = (int)strlen((char *)buffer);
    while (len > 0 && isspace(buffer[len-1])) len--;
    buffer[len] = 0;
    if (len == 0) break;

    p = buffer;
    while (isspace(*p)) p++;

    q = dbuffer;
    while ((c = *p++) != 0)
      {
      int i = 0;
      int n = 0;
      if (c == '\\') switch ((c = *p++))
        {
        case 'a': c =    7; break;
        case 'b': c = '\b'; break;
        case 'e': c =   27; break;
        case 'f': c = '\f'; break;
        case 'n': c = '\n'; break;
        case 'r': c = '\r'; break;
        case 't': c = '\t'; break;
        case 'v': c = '\v'; break;

        case '0': case '1': case '2': case '3':
        case '4': case '5': case '6': case '7':
        c -= '0';
        while (i++ < 2 && isdigit(*p) && *p != '8' && *p != '9')
          c = c * 8 + *p++ - '0';
        break;

        case 'x':

        /* Handle \x{..} specially - new Perl thing for utf8 */

        if (*p == '{')
          {
          unsigned char *pt = p;
          c = 0;
          while (isxdigit(*(++pt)))
            c = c * 16 + tolower(*pt) - ((isdigit(*pt))? '0' : 'W');
          if (*pt == '}')
            {
            unsigned char buffer[8];
            int ii, utn;
            utn = ord2utf8(c, buffer);
            for (ii = 0; ii < utn - 1; ii++) *q++ = buffer[ii];
            c = buffer[ii];   /* Last byte */
            p = pt + 1;
            break;
            }
          /* Not correct form; fall through */
          }

        /* Ordinary \x */

        c = 0;
        while (i++ < 2 && isxdigit(*p))
          {
          c = c * 16 + tolower(*p) - ((isdigit(*p))? '0' : 'W');
          p++;
          }
        break;

        case 0:   /* Allows for an empty line */
        p--;
        continue;

        case 'A':  /* Option setting */
        options |= PCRE_ANCHORED;
        continue;

        case 'B':
        options |= PCRE_NOTBOL;
        continue;

        case 'C':
        while(isdigit(*p)) n = n * 10 + *p++ - '0';
        copystrings |= 1 << n;
        continue;

        case 'G':
        while(isdigit(*p)) n = n * 10 + *p++ - '0';
        getstrings |= 1 << n;
        continue;

        case 'L':
        getlist = 1;
        continue;

        case 'N':
        options |= PCRE_NOTEMPTY;
        continue;

        case 'O':
        while(isdigit(*p)) n = n * 10 + *p++ - '0';
        if (n > size_offsets_max)
          {
          size_offsets_max = n;
          free(offsets);
          use_offsets = offsets = malloc(size_offsets_max * sizeof(int));
          if (offsets == NULL)
            {
            printf("** Failed to get %d bytes of memory for offsets vector\n",
              size_offsets_max * sizeof(int));
            return 1;
            }
          }
        use_size_offsets = n;
        if (n == 0) use_offsets = NULL;
        continue;

        case 'Z':
        options |= PCRE_NOTEOL;
        continue;
        }
      *q++ = c;
      }
    *q = 0;
    len = q - dbuffer;

    /* Handle matching via the POSIX interface, which does not
    support timing. */

#if !defined NOPOSIX
    if (posix || do_posix)
      {
      int rc;
      int eflags = 0;
      regmatch_t *pmatch = malloc(sizeof(regmatch_t) * use_size_offsets);
      if ((options & PCRE_NOTBOL) != 0) eflags |= REG_NOTBOL;
      if ((options & PCRE_NOTEOL) != 0) eflags |= REG_NOTEOL;

      rc = regexec(&preg, (const char *)bptr, use_size_offsets, pmatch, eflags);

      if (rc != 0)
        {
        (void)regerror(rc, &preg, (char *)buffer, sizeof(buffer));
        fprintf(outfile, "No match: POSIX code %d: %s\n", rc, buffer);
        }
      else
        {
        size_t i;
        for (i = 0; i < use_size_offsets; i++)
          {
          if (pmatch[i].rm_so >= 0)
            {
            fprintf(outfile, "%2d: ", (int)i);
            pchars(dbuffer + pmatch[i].rm_so,
              pmatch[i].rm_eo - pmatch[i].rm_so, utf8);
            fprintf(outfile, "\n");
            if (i == 0 && do_showrest)
              {
              fprintf(outfile, " 0+ ");
              pchars(dbuffer + pmatch[i].rm_eo, len - pmatch[i].rm_eo, utf8);
              fprintf(outfile, "\n");
              }
            }
          }
        }
      free(pmatch);
      }

    /* Handle matching via the native interface - repeats for /g and /G */

    else
#endif  /* !defined NOPOSIX */

    for (;; gmatched++)    /* Loop for /g or /G */
      {
      if (timeit)
        {
        register int i;
        clock_t time_taken;
        clock_t start_time = clock();
        for (i = 0; i < LOOPREPEAT; i++)
          count = pcre_exec(re, extra, (char *)bptr, len,
            start_offset, options | g_notempty, use_offsets, use_size_offsets);
        time_taken = clock() - start_time;
        fprintf(outfile, "Execute time %.3f milliseconds\n",
          ((double)time_taken * 1000.0)/
          ((double)LOOPREPEAT * (double)CLOCKS_PER_SEC));
        }

      count = pcre_exec(re, extra, (char *)bptr, len,
        start_offset, options | g_notempty, use_offsets, use_size_offsets);

      if (count == 0)
        {
        fprintf(outfile, "Matched, but too many substrings\n");
        count = use_size_offsets/3;
        }

      /* Matched */

      if (count >= 0)
        {
        int i;
        for (i = 0; i < count * 2; i += 2)
          {
          if (use_offsets[i] < 0)
            fprintf(outfile, "%2d: <unset>\n", i/2);
          else
            {
            fprintf(outfile, "%2d: ", i/2);
            pchars(bptr + use_offsets[i], use_offsets[i+1] - use_offsets[i], utf8);
            fprintf(outfile, "\n");
            if (i == 0)
              {
              if (do_showrest)
                {
                fprintf(outfile, " 0+ ");
                pchars(bptr + use_offsets[i+1], len - use_offsets[i+1], utf8);
                fprintf(outfile, "\n");
                }
              }
            }
          }

        for (i = 0; i < 32; i++)
          {
          if ((copystrings & (1 << i)) != 0)
            {
            char copybuffer[16];
            int rc = pcre_copy_substring((char *)bptr, use_offsets, count,
              i, copybuffer, sizeof(copybuffer));
            if (rc < 0)
              fprintf(outfile, "copy substring %d failed %d\n", i, rc);
            else
              fprintf(outfile, "%2dC %s (%d)\n", i, copybuffer, rc);
            }
          }

        for (i = 0; i < 32; i++)
          {
          if ((getstrings & (1 << i)) != 0)
            {
            const char *substring;
            int rc = pcre_get_substring((char *)bptr, use_offsets, count,
              i, &substring);
            if (rc < 0)
              fprintf(outfile, "get substring %d failed %d\n", i, rc);
            else
              {
              fprintf(outfile, "%2dG %s (%d)\n", i, substring, rc);
              /* free((void *)substring); */
              pcre_free_substring(substring);
              }
            }
          }

        if (getlist)
          {
          const char **stringlist;
          int rc = pcre_get_substring_list((char *)bptr, use_offsets, count,
            &stringlist);
          if (rc < 0)
            fprintf(outfile, "get substring list failed %d\n", rc);
          else
            {
            for (i = 0; i < count; i++)
              fprintf(outfile, "%2dL %s\n", i, stringlist[i]);
            if (stringlist[i] != NULL)
              fprintf(outfile, "string list not terminated by NULL\n");
            /* free((void *)stringlist); */
            pcre_free_substring_list(stringlist);
            }
          }
        }

      /* Failed to match. If this is a /g or /G loop and we previously set
      g_notempty after a null match, this is not necessarily the end.
      We want to advance the start offset, and continue. Fudge the offset
      values to achieve this. We won't be at the end of the string - that
      was checked before setting g_notempty. */

      else
        {
        if (g_notempty != 0)
          {
          use_offsets[0] = start_offset;
          use_offsets[1] = start_offset + 1;
          }
        else
          {
          if (gmatched == 0)   /* Error if no previous matches */
            {
            if (count == -1) fprintf(outfile, "No match\n");
              else fprintf(outfile, "Error %d\n", count);
            }
          break;  /* Out of the /g loop */
          }
        }

      /* If not /g or /G we are done */

      if (!do_g && !do_G) break;

      /* If we have matched an empty string, first check to see if we are at
      the end of the subject. If so, the /g loop is over. Otherwise, mimic
      what Perl's /g options does. This turns out to be rather cunning. First
      we set PCRE_NOTEMPTY and PCRE_ANCHORED and try the match again at the
      same point. If this fails (picked up above) we advance to the next
      character. */

      g_notempty = 0;
      if (use_offsets[0] == use_offsets[1])
        {
        if (use_offsets[0] == len) break;
        g_notempty = PCRE_NOTEMPTY | PCRE_ANCHORED;
        }

      /* For /g, update the start offset, leaving the rest alone */

      if (do_g) start_offset = use_offsets[1];

      /* For /G, update the pointer and length */

      else
        {
        bptr += use_offsets[1];
        len -= use_offsets[1];
        }
      }  /* End of loop for /g and /G */
    }    /* End of loop for data lines */

  CONTINUE:

#if !defined NOPOSIX
  if (posix || do_posix) regfree(&preg);
#endif

  if (re != NULL) free(re);
  if (extra != NULL) free(extra);
  if (tables != NULL)
    {
    free((void *)tables);
    setlocale(LC_CTYPE, "C");
    }
  }

fprintf(outfile, "\n");
return 0;
}
Exemple #22
0
DetectUrilenData *DetectUrilenParse (char *urilenstr)
{

    DetectUrilenData *urilend = NULL;
    char *arg1 = NULL;
    char *arg2 = NULL;
    char *arg3 = NULL;
    char *arg4 = NULL;
    char *arg5 = NULL;
#define MAX_SUBSTRINGS 30
    int ret = 0, res = 0;
    int ov[MAX_SUBSTRINGS];

    ret = pcre_exec(parse_regex, parse_regex_study, urilenstr, strlen(urilenstr),
                    0, 0, ov, MAX_SUBSTRINGS);
    if (ret < 3 || ret > 6) {
        SCLogError(SC_ERR_PCRE_PARSE, "urilen option pcre parse error: \"%s\"", urilenstr);
        goto error;
    }
    const char *str_ptr;

    SCLogDebug("ret %d", ret);

    res = pcre_get_substring((char *)urilenstr, ov, MAX_SUBSTRINGS, 1, &str_ptr);
    if (res < 0) {
        SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed");
        goto error;
    }
    arg1 = (char *) str_ptr;
    SCLogDebug("Arg1 \"%s\"", arg1);

    res = pcre_get_substring((char *)urilenstr, ov, MAX_SUBSTRINGS, 2, &str_ptr);
    if (res < 0) {
        SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed");
        goto error;
    }
    arg2 = (char *) str_ptr;
    SCLogDebug("Arg2 \"%s\"", arg2);

    if (ret > 3) {
        res = pcre_get_substring((char *)urilenstr, ov, MAX_SUBSTRINGS, 3, &str_ptr);
        if (res < 0) {
            SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed");
            goto error;
        }
        arg3 = (char *) str_ptr;
        SCLogDebug("Arg3 \"%s\"", arg3);

        if (ret > 4) {
            res = pcre_get_substring((char *)urilenstr, ov, MAX_SUBSTRINGS, 4, &str_ptr);
            if (res < 0) {
                SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed");
                goto error;
            }
            arg4 = (char *) str_ptr;
            SCLogDebug("Arg4 \"%s\"", arg4);
        }
        if (ret > 5) {
            res = pcre_get_substring((char *)urilenstr, ov, MAX_SUBSTRINGS, 5, &str_ptr);
            if (res < 0) {
                SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed");
                goto error;
            }
            arg5 = (char *) str_ptr;
            SCLogDebug("Arg5 \"%s\"", arg5);
        }
    }

    urilend = SCMalloc(sizeof (DetectUrilenData));
    if (unlikely(urilend == NULL))
    goto error;
    memset(urilend, 0, sizeof(DetectUrilenData));

    if (arg1[0] == '<')
        urilend->mode = DETECT_URILEN_LT;
    else if (arg1[0] == '>')
        urilend->mode = DETECT_URILEN_GT;
    else
        urilend->mode = DETECT_URILEN_EQ;

    if (arg3 != NULL && strcmp("<>", arg3) == 0) {
        if (strlen(arg1) != 0) {
            SCLogError(SC_ERR_INVALID_ARGUMENT,"Range specified but mode also set");
            goto error;
        }
        urilend->mode = DETECT_URILEN_RA;
    }

    /** set the first urilen value */
    if (ByteExtractStringUint16(&urilend->urilen1,10,strlen(arg2),arg2) <= 0){
        SCLogError(SC_ERR_INVALID_ARGUMENT,"Invalid size :\"%s\"",arg2);
        goto error;
    }

    /** set the second urilen value if specified */
    if (arg4 != NULL && strlen(arg4) > 0) {
        if (urilend->mode != DETECT_URILEN_RA) {
            SCLogError(SC_ERR_INVALID_ARGUMENT,"Multiple urilen values specified"
                                           " but mode is not range");
            goto error;
        }

        if(ByteExtractStringUint16(&urilend->urilen2,10,strlen(arg4),arg4) <= 0)
        {
            SCLogError(SC_ERR_INVALID_ARGUMENT,"Invalid size :\"%s\"",arg4);
            goto error;
        }

        if (urilend->urilen2 <= urilend->urilen1){
            SCLogError(SC_ERR_INVALID_ARGUMENT,"urilen2:%"PRIu16" <= urilen:"
                        "%"PRIu16"",urilend->urilen2,urilend->urilen1);
            goto error;
        }
    }

    if (arg5 != NULL) {
        if (strcasecmp("raw", arg5) == 0) {
            urilend->raw_buffer = 1;
        }
    }

    pcre_free_substring(arg1);
    pcre_free_substring(arg2);
    if (arg3 != NULL)
        pcre_free_substring(arg3);
    if (arg4 != NULL)
        pcre_free_substring(arg4);
    if (arg5 != NULL)
        pcre_free_substring(arg5);
    return urilend;

error:
    if (urilend)
        SCFree(urilend);
    if (arg1 != NULL)
        SCFree(arg1);
    if (arg2 != NULL)
        SCFree(arg2);
    if (arg3 != NULL)
        SCFree(arg3);
    if (arg4 != NULL)
        SCFree(arg4);
    return NULL;
}
int flt_urlrewrite_execute(cf_configuration_t *fdc,cf_configuration_t *fvc,const u_char *uri,u_char **new_uri) {
  unsigned int i, j, f;
  int res;
  int nbr;
  u_char buf[3];
  u_char *ptr;
  cf_string_t dest;
  size_t len = 0;
  flt_urlrewrite_rule_t *current_rule = NULL;

  if(!flt_urlrewrite_rules || !flt_urlrewrite_rules->elements) {
    return FLT_DECLINE;
  }
  
  for(i = 0; i < flt_urlrewrite_rules->elements; i++) {
    current_rule = cf_array_element_at(flt_urlrewrite_rules,i);
    if(!flt_urlrewrite_is_macro_true(current_rule->macro_tree)) {
      continue;
    }
    res = pcre_exec(current_rule->regexp, current_rule->regexp_extra, uri, strlen(uri), 0, 0, current_rule->match_arr,(current_rule->match_count + 1) * 3);
    if(res >= 0) { // didn't match
      break; // matched
    }
  }

  if(i == flt_urlrewrite_rules->elements) { // nothing matched
    return FLT_DECLINE;
  }
  
  cf_str_init (&dest);
  len = strlen(current_rule->replacement);
  for(j = 0; j < len; j++) {
    f = 0;
    if(current_rule->replacement[j] == '$') { // replacement varialbe
      if(current_rule->replacement[j+1] == '{') {
        if(isdigit(current_rule->replacement[j+2])) {
          if(isdigit(current_rule->replacement[j+3]) && current_rule->replacement[j+4] == '}') {
            strncpy(buf, &current_rule->replacement[j+2], 2);
            buf[2] = 0;
            f = 4;
          }
          else if(current_rule->replacement[j+3] == '}') {
            strncpy(buf, &current_rule->replacement[j+2], 1);
            buf[1] = 0;
            f = 3;
          }
        }
      }
      else if(isdigit(current_rule->replacement[j+1])) {
        if(isdigit(current_rule->replacement[j+2])) {
          strncpy(buf, &current_rule->replacement[j+1], 2);
          buf[2] = 0;
          f = 2;
        } else {
          strncpy(buf, &current_rule->replacement[j+1], 1);
          buf[1] = 0;
          f = 1;
        }
      }
      if(f) {
        nbr = atoi(buf);
        res = pcre_get_substring(uri,current_rule->match_arr,(current_rule->match_count + 1) * 3,nbr,(const char **)&ptr);
        // error => ignore
        if(res < 0) {
          cf_str_char_append(&dest, current_rule->replacement[j]);
          continue;
        }
        cf_str_chars_append(&dest, ptr, res);
        pcre_free_substring(ptr);
        j += f;
        continue;
      }
    }
    cf_str_char_append(&dest, current_rule->replacement[j]);
  }
  
  // if the new string has not got a length
  if(!dest.len) {
    // make sure there's a buffer
    cf_str_char_append(&dest, '\0');
  }
  
  *new_uri = dest.content;
  free((void *)uri);

  return FLT_EXIT;
}
/**
 * \brief This function is used to parse ssl_version data passed via
 *        keyword: "ssl_version"
 *
 * \param str Pointer to the user provided options
 *
 * \retval ssl pointer to DetectSslVersionData on success
 * \retval NULL on failure
 */
static DetectSslVersionData *DetectSslVersionParse(const char *str)
{
    DetectSslVersionData *ssl = NULL;
	#define MAX_SUBSTRINGS 30
    int ret = 0, res = 0;
    int ov[MAX_SUBSTRINGS];

    ret = pcre_exec(parse_regex, parse_regex_study, str, strlen(str), 0, 0,
                    ov, MAX_SUBSTRINGS);

    if (ret < 1 || ret > 5) {
        SCLogError(SC_ERR_PCRE_MATCH, "invalid ssl_version option");
        goto error;
    }

    if (ret > 1) {
        const char *str_ptr;
        char *orig;
        uint8_t found = 0, neg = 0;
        char *tmp_str;

        /* We have a correct ssl_version options */
        ssl = SCCalloc(1, sizeof (DetectSslVersionData));
        if (unlikely(ssl == NULL))
            goto error;

        int i;
        for (i = 1; i < ret; i++) {
            res = pcre_get_substring((char *) str, ov, MAX_SUBSTRINGS, i, &str_ptr);
            if (res < 0) {
                SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed");
                if (found == 0)
                    goto error;
                break;
            }

            orig = SCStrdup((char*) str_ptr);
            if (unlikely(orig == NULL)) {
                goto error;
            }
            tmp_str = orig;

            /* Let's see if we need to scape "'s */
            if (tmp_str[0] == '"') {
                tmp_str[strlen(tmp_str) - 1] = '\0';
                tmp_str += 1;
            }


            if (tmp_str[0] == '!') {
                neg = 1;
                tmp_str++;
            }

            if (strncasecmp("sslv2", tmp_str, 5) == 0) {
                ssl->data[SSLv2].ver = SSL_VERSION_2;
                if (neg == 1)
                    ssl->data[SSLv2].flags |= DETECT_SSL_VERSION_NEGATED;
            } else if (strncasecmp("sslv3", tmp_str, 5) == 0) {
                ssl->data[SSLv3].ver = SSL_VERSION_3;
                if (neg == 1)
                    ssl->data[SSLv3].flags |= DETECT_SSL_VERSION_NEGATED;
            } else if (strncasecmp("tls1.0", tmp_str, 6) == 0) {
                ssl->data[TLS10].ver = TLS_VERSION_10;
                if (neg == 1)
                    ssl->data[TLS10].flags |= DETECT_SSL_VERSION_NEGATED;
            } else if (strncasecmp("tls1.1", tmp_str, 6) == 0) {
                ssl->data[TLS11].ver = TLS_VERSION_11;
                if (neg == 1)
                    ssl->data[TLS11].flags |= DETECT_SSL_VERSION_NEGATED;
            } else if (strncasecmp("tls1.2", tmp_str, 6) == 0) {
                ssl->data[TLS12].ver = TLS_VERSION_12;
                if (neg == 1)
                    ssl->data[TLS12].flags |= DETECT_SSL_VERSION_NEGATED;
            }  else if (strcmp(tmp_str, "") == 0) {
                SCFree(orig);
                if (found == 0)
                    goto error;
                break;
            } else {
                SCLogError(SC_ERR_INVALID_VALUE, "Invalid value");
                SCFree(orig);
                goto error;
            }

            found = 1;
            neg = 0;
            SCFree(orig);
            pcre_free_substring(str_ptr);
        }
    }

    return ssl;

error:
    if (ssl != NULL)
        DetectSslVersionFree(ssl);
    return NULL;

}
Exemple #25
0
/**
 * \brief This function is used to parse fingerprint passed via keyword: "fingerprint"
 *
 * \param idstr Pointer to the user provided fingerprint option
 *
 * \retval pointer to DetectTlsData on success
 * \retval NULL on failure
 */
static DetectTlsData *DetectTlsFingerprintParse (char *str)
{
    DetectTlsData *tls = NULL;
#define MAX_SUBSTRINGS 30
    int ret = 0, res = 0;
    int ov[MAX_SUBSTRINGS];
    const char *str_ptr;
    char *orig;
    char *tmp_str;
    uint32_t flag = 0;

    ret = pcre_exec(fingerprint_parse_regex, fingerprint_parse_regex_study, str, strlen(str), 0, 0,
                    ov, MAX_SUBSTRINGS);

    if (ret != 3) {
        SCLogError(SC_ERR_PCRE_MATCH, "invalid tls.fingerprint option");
        goto error;
    }

    res = pcre_get_substring((char *)str, ov, MAX_SUBSTRINGS, 1, &str_ptr);
    if (res < 0) {
        SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed");
        goto error;
    }
    if (str_ptr[0] == '!')
        flag = DETECT_CONTENT_NEGATED;
    pcre_free_substring(str_ptr);

    res = pcre_get_substring((char *)str, ov, MAX_SUBSTRINGS, 2, &str_ptr);
    if (res < 0) {
        SCLogError(SC_ERR_PCRE_GET_SUBSTRING, "pcre_get_substring failed");
        goto error;
    }

    /* We have a correct id option */
    tls = SCMalloc(sizeof(DetectTlsData));
    if (unlikely(tls == NULL))
        goto error;
    tls->fingerprint = NULL;
    tls->flags = flag;

    orig = SCStrdup((char*)str_ptr);
    if (unlikely(orig == NULL)) {
        goto error;
    }
    pcre_free_substring(str_ptr);

    tmp_str=orig;

    /* Let's see if we need to escape "'s */
    if (tmp_str[0] == '"')
    {
        tmp_str[strlen(tmp_str) - 1] = '\0';
        tmp_str += 1;
    }

    tls->fingerprint = SCStrdup(tmp_str);
    if (tls->fingerprint == NULL) {
        SCLogError(SC_ERR_MEM_ALLOC, "Unable to allocate fingerprint");
    }

    SCFree(orig);

    SCLogDebug("will look for TLS fingerprint %s", tls->fingerprint);

    return tls;

error:
    if (tls != NULL)
        DetectTlsFingerprintFree(tls);
    return NULL;

}
Exemple #26
0
pcre_error_code pcre_private(char *INPUT_LINE, char *INPUT_PAT, int *Output_Start, int *Output_End, char*** _pstCapturedString, int* _piCapturedStringCount)
{
    /* ALL strings are managed as UTF-8 by default */
    int options = PCRE_UTF8;
    int size_offsets = 45;
    int size_offsets_max;
    int *offsets = NULL;
    int all_use_dfa = 0;
    BOOL LOOP_PCRE_TST = FALSE;

    /* These vectors store, end-to-end, a list of captured substring names. Assume
    that 1024 is plenty long enough for the few names we'll be testing. */

    char copynames[1024];
    char getnames[1024];

    char *copynamesptr = NULL;
    char *getnamesptr = NULL;

    int rc = 0;
    (void)pcre_config(PCRE_CONFIG_UTF8, &rc);
    if (rc != 1)
    {
        return UTF8_NOT_SUPPORTED;
    }

    /* bug 3891 */
    /* backslash characters are not interpreted for input */
    buffer = strsub(INPUT_LINE, "\\", "\\\\");

    size_offsets_max = size_offsets;
    offsets = (int *)MALLOC(size_offsets_max * sizeof(int));
    if (offsets == NULL)
    {
        if (buffer)
        {
            FREE(buffer);
            buffer = NULL;
        }
        return NOT_ENOUGH_MEMORY_FOR_VECTOR;
    }
    /* Main loop */
    LOOP_PCRE_TST = FALSE;
    while (!LOOP_PCRE_TST)
    {
        pcre *re = NULL;
        pcre_extra *extra = NULL;
        const char *error = NULL;
        char *back_p = NULL;
        char *p = NULL;
        char *pp = NULL;
        char *ppp = NULL;
        const unsigned char *tables = NULL;
        int do_G = 0;
        int do_g = 0;
        int erroroffset = 0, len = 0, delimiter;

        LOOP_PCRE_TST = TRUE;
        p = strdup(INPUT_PAT);
        back_p = p;
        while (isspace(*p))
        {
            p++;
        }
        if (*p == 0)
        {
            continue;
        }
        /* In-line pattern (the usual case). Get the delimiter and seek the end of
        the pattern; if is isn't complete, read more. */

        delimiter = *p++;

        if (isalnum(delimiter) || delimiter == '\\')
        {
            if (buffer)
            {
                FREE(buffer);
                buffer = NULL;
            }
            if (offsets)
            {
                FREE(offsets);
                offsets = NULL;
            }
            if (back_p)
            {
                FREE(back_p);
                back_p = NULL;
            }
            return DELIMITER_NOT_ALPHANUMERIC;
        }

        pp = p;

        while (*pp != 0)
        {
            if (*pp == '\\' && pp[1] != 0)
            {
                pp++;
            }
            else if (*pp == delimiter)
            {
                break;
            }
            pp++;
        }

        /* If the delimiter can't be found, it's a syntax error */
        if (*pp == 0)
        {
            if (buffer)
            {
                FREE(buffer);
                buffer = NULL;
            }
            if (offsets)
            {
                FREE(offsets);
                offsets = NULL;
            }
            if (back_p)
            {
                FREE(back_p);
                back_p = NULL;
            }
            if (offsets)
            {
                FREE(offsets);
            }
            return CAN_NOT_COMPILE_PATTERN;
        }

        /* If the first character after the delimiter is backslash, make
        the pattern end with backslash. This is purely to provide a way
        of testing for the error message when a pattern ends with backslash. */

        if (pp[1] == '\\')
        {
            *pp++ = '\\';
        }

        /* Terminate the pattern at the delimiter, and save a copy of the pattern
        for callouts. */

        *pp++ = 0;

        /* Look for options after final delimiter */

        //options = 8192;

        while (*pp != 0)
        {
            switch (*pp++)
            {
                case 'f':
                    options |= PCRE_FIRSTLINE;
                    break;
                case 'g':
                    do_g = 1;
                    break;
                case 'i':
                    options |= PCRE_CASELESS;
                    break;
                case 'm':
                    options |= PCRE_MULTILINE;
                    break;
                case 's':
                    options |= PCRE_DOTALL;
                    break;
                case 'x':
                    options |= PCRE_EXTENDED;
                    break;
                case '+':
                    break;
                case 'A':
                    options |= PCRE_ANCHORED;
                    break;
                case 'B':
                    break;
                case 'C':
                    options |= PCRE_AUTO_CALLOUT;
                    break;
                case 'D':
                    break;
                case 'E':
                    options |= PCRE_DOLLAR_ENDONLY;
                    break;
                case 'F':
                    break;
                case 'G':
                    do_G = 1;
                    break;
                case 'I':
                    break;
                case 'J':
                    options |= PCRE_DUPNAMES;
                    break;
                case 'M':
                    break;
                case 'N':
                    options |= PCRE_NO_AUTO_CAPTURE;
                    break;
                case 'S':
                    break;
                case 'U':
                    options |= PCRE_UNGREEDY;
                    break;
                case 'X':
                    options |= PCRE_EXTRA;
                    break;
                case 'Z':
                    break;
                case '8':
                {
                    int rc = 0;
                    (void)pcre_config(PCRE_CONFIG_UTF8, &rc);
                    if (rc != 1)
                    {
                        if (buffer)
                        {
                            FREE(buffer);
                            buffer = NULL;
                        }
                        if (offsets)
                        {
                            FREE(offsets);
                        }
                        return UTF8_NOT_SUPPORTED;
                    }
                    options |= PCRE_UTF8;
                }
                break;
                case '?':
                    options |= PCRE_NO_UTF8_CHECK;
                    break;
                case 'L':
                    ppp = pp;
                    /* The '\r' test here is so that it works on Windows. */
                    /* The '0' test is just in case this is an unterminated line. */
                    while (*ppp != 0 && *ppp != '\n' && *ppp != '\r' && *ppp != ' ')
                    {
                        ppp++;
                    }
                    *ppp = 0;
                    if (setlocale(LC_CTYPE, (const char *)pp) == NULL)
                    {
                        goto SKIP_DATA;
                    }

                    tables = pcre_maketables();
                    pp = ppp;
                    break;
                case '>':
                    while (*pp != 0)
                    {
                        pp++;
                    }
                    while (isspace(pp[-1]))
                    {
                        pp--;
                    }
                    *pp = 0;
                    break;
                case '<':
                {
                    while (*pp++ != '>')
                    {
                        ;
                    }
                }
                break;
                case '\r':                      /* So that it works in Windows */
                case '\n':
                case ' ':
                    break;

                default:
                    goto SKIP_DATA;
            }
        }

        /* Handle compiling via the POSIX interface, which doesn't support the
        timing, showing, or debugging options, nor the ability to pass over
        local character tables. */


        {
            re = pcre_compile((char *)p, options, &error, &erroroffset, tables);
            /* Compilation failed; go back for another re, skipping to blank line
            if non-interactive. */
            if (re == NULL)
            {
SKIP_DATA:
                if (buffer)
                {
                    FREE(buffer);
                    buffer = NULL;
                }
                if (offsets)
                {
                    FREE(offsets);
                    offsets = NULL;
                }
                if (tables)
                {
                    (*pcre_free)((void*)tables);
                    tables = NULL;
                }
                if (extra)
                {
                    FREE(extra);
                    extra = NULL;
                }
                if (back_p)
                {
                    FREE(back_p);
                    back_p = NULL;
                }
                return CAN_NOT_COMPILE_PATTERN;
            }

        }        /* End of non-POSIX compile */

        /* Read data lines and test them */
        {
            char *q = NULL;
            char *bptr = NULL;
            int *use_offsets = offsets;
            int use_size_offsets = size_offsets;
            int callout_data = 0;
            int callout_data_set = 0;
            int count = 0;
            int c = 0;
            int copystrings = 0;
            int find_match_limit = 0;
            int getstrings = 0;
            int gmatched = 0;
            int start_offset = 0;
            int g_notempty = 0;
            int use_dfa = 0;

            options = 0;
            *copynames = 0;
            *getnames = 0;

            copynamesptr = copynames;
            getnamesptr = getnames;

            callout_count = 0;
            callout_fail_count = 999999;
            callout_fail_id = -1;

            if (extra != NULL)
            {
                extra->flags &= ~(PCRE_EXTRA_MATCH_LIMIT | PCRE_EXTRA_MATCH_LIMIT_RECURSION);
            }
            p = buffer;
            bptr = q = buffer;
            while ((c = *p++) != 0)
            {
                int i = 0;
                int n = 0;

                if (c == '\\') switch ((c = *p++))
                    {
                        case 'a':
                            c =    7;
                            break;
                        case 'b':
                            c = '\b';
                            break;
                        case 'e':
                            c =   27;
                            break;
                        case 'f':
                            c = '\f';
                            break;
                        case 'n':
                            c = '\n';
                            break;
                        case 'r':
                            c = '\r';
                            break;
                        case 't':
                            c = '\t';
                            break;
                        case 'v':
                            c = '\v';
                            break;
                        case '0':
                        case '1':
                        case '2':
                        case '3':
                        case '4':
                        case '5':
                        case '6':
                        case '7':
                            c -= '0';
                            while (i++ < 2 && isdigit(*p) && *p != '8' && *p != '9')
                            {
                                c = c * 8 + *p++ - '0';
                            }
                            break;
                        case 'x':
                            /* Ordinary \x */
                            c = 0;
                            while (i++ < 2 && isxdigit(*p))
                            {
                                c = c * 16 + tolower(*p) - ((isdigit(*p)) ? '0' : 'W');
                                p++;
                            }
                            break;
                        case 0:   /* \ followed by EOF allows for an empty line */
                            p--;
                            continue;
                        case '>':
                            while (isdigit(*p))
                            {
                                start_offset = start_offset * 10 + *p++ - '0';
                            }
                            continue;
                        case 'A':  /* Option setting */
                            options |= PCRE_ANCHORED;
                            continue;
                        case 'B':
                            options |= PCRE_NOTBOL;
                            continue;
                        case 'C':
                            if (isdigit(*p))    /* Set copy string */
                            {
                                while (isdigit(*p))
                                {
                                    n = n * 10 + *p++ - '0';
                                }
                                copystrings |= 1 << n;
                            }
                            else if (isalnum(*p))
                            {
                                char *npp = copynamesptr;
                                while (isalnum(*p))
                                {
                                    *npp++ = *p++;
                                }
                                *npp++ = 0;
                                *npp = 0;
                                pcre_get_stringnumber(re, (char *)copynamesptr);
                                copynamesptr = npp;
                            }
                            else if (*p == '+')
                            {
                                p++;
                            }
                            else if (*p == '-')
                            {
                                p++;
                            }
                            else if (*p == '!')
                            {
                                callout_fail_id = 0;
                                p++;
                                while (isdigit(*p))
                                {
                                    callout_fail_id = callout_fail_id * 10 + *p++ - '0';
                                }
                                callout_fail_count = 0;
                                if (*p == '!')
                                {
                                    p++;
                                    while (isdigit(*p))
                                    {
                                        callout_fail_count = callout_fail_count * 10 + *p++ - '0';
                                    }
                                }
                            }
                            else if (*p == '*')
                            {
                                int sign = 1;
                                callout_data = 0;
                                if (*(++p) == '-')
                                {
                                    sign = -1;
                                    p++;
                                }
                                while (isdigit(*p))
                                {
                                    callout_data = callout_data * 10 + *p++ - '0';
                                }
                                callout_data *= sign;
                                callout_data_set = 1;
                            }
                            continue;
                        case 'G':
                            if (isdigit(*p))
                            {
                                while (isdigit(*p))
                                {
                                    n = n * 10 + *p++ - '0';
                                }
                                getstrings |= 1 << n;
                            }
                            else if (isalnum(*p))
                            {
                                char *npp = getnamesptr;
                                while (isalnum(*p))
                                {
                                    *npp++ = *p++;
                                }
                                *npp++ = 0;
                                *npp = 0;
                                pcre_get_stringnumber(re, (char *)getnamesptr);
                                getnamesptr = npp;
                            }
                            continue;
                        case 'L':
                            continue;
                        case 'M':
                            find_match_limit = 1;
                            continue;
                        case 'N':
                            options |= PCRE_NOTEMPTY;
                            continue;
                        case 'O':
                            while (isdigit(*p))
                            {
                                n = n * 10 + *p++ - '0';
                            }
                            if (n > size_offsets_max)
                            {
                                size_offsets_max = n;
                                if (offsets)
                                {
                                    FREE(offsets);
                                }
                                use_offsets = offsets = (int *)MALLOC(size_offsets_max * sizeof(int));
                            }
                            use_size_offsets = n;
                            if (n == 0)
                            {
                                use_offsets = NULL;    /* Ensures it can't write to it */
                            }
                            continue;
                        case 'P':
                            options |= PCRE_PARTIAL;
                            continue;
                        case 'Q':
                            while (isdigit(*p))
                            {
                                n = n * 10 + *p++ - '0';
                            }
                            if (extra == NULL)
                            {
                                extra = (pcre_extra *)MALLOC(sizeof(pcre_extra));
                                extra->flags = 0;
                            }
                            extra->flags |= PCRE_EXTRA_MATCH_LIMIT_RECURSION;
                            extra->match_limit_recursion = n;
                            continue;
                        case 'q':
                            while (isdigit(*p))
                            {
                                n = n * 10 + *p++ - '0';
                            }
                            if (extra == NULL)
                            {
                                extra = (pcre_extra *)MALLOC(sizeof(pcre_extra));
                                extra->flags = 0;
                            }
                            extra->flags |= PCRE_EXTRA_MATCH_LIMIT;
                            extra->match_limit = n;
                            continue;
#if !defined NODFA
                        case 'R':
                            options |= PCRE_DFA_RESTART;
                            continue;
#endif
                        case 'S':

                            continue;
                        case 'Z':
                            options |= PCRE_NOTEOL;
                            continue;
                        case '?':
                            options |= PCRE_NO_UTF8_CHECK;
                            continue;
                        case '<':
                        {
                            while (*p++ != '>')
                            {
                                ;
                            }
                        }
                        continue;
                    }
                *q++ = (char)c;
            }
            *q = 0;
            len = (int)(q - buffer);
            if ((all_use_dfa || use_dfa) && find_match_limit)
            {
                if (buffer)
                {
                    FREE(buffer);
                    buffer = NULL;
                }
                if (offsets)
                {
                    FREE(offsets);
                    offsets = NULL;
                }
                if (p)
                {
                    FREE(p);
                    p = NULL;
                }
                if (re)
                {
                    (*pcre_free)(re);
                    re = NULL;
                }
                if (tables)
                {
                    (*pcre_free)((void*)tables);
                    tables = NULL;
                }
                if (extra)
                {
                    FREE(extra);
                    extra = NULL;
                }
                return LIMIT_NOT_RELEVANT_FOR_DFA_MATCHING;
            }
            /* Handle matching via the POSIX interface, which does not
            support timing or playing with the match limit or callout data. */
            for (;; gmatched++)    /* Loop for /g or /G */
            {

                /* If find_match_limit is set, we want to do repeated matches with
                varying limits in order to find the minimum value for the match limit and
                for the recursion limit. */

                if (find_match_limit)
                {
                    if (extra == NULL)
                    {
                        extra = (pcre_extra *)MALLOC(sizeof(pcre_extra));
                        extra->flags = 0;
                    }

                    (void)check_match_limit(re, extra, bptr, len, start_offset,
                                            options | g_notempty, use_offsets, use_size_offsets,
                                            PCRE_EXTRA_MATCH_LIMIT, &(extra->match_limit),
                                            PCRE_ERROR_MATCHLIMIT);

                    count = check_match_limit(re, extra, bptr, len, start_offset,
                                              options | g_notempty, use_offsets, use_size_offsets,
                                              PCRE_EXTRA_MATCH_LIMIT_RECURSION, &(extra->match_limit_recursion),
                                              PCRE_ERROR_RECURSIONLIMIT);
                }
                /* If callout_data is set, use the interface with additional data */
                else if (callout_data_set)
                {
                    if (extra == NULL)
                    {
                        extra = (pcre_extra *)MALLOC(sizeof(pcre_extra));
                        extra->flags = 0;
                    }
                    extra->flags |= PCRE_EXTRA_CALLOUT_DATA;
                    extra->callout_data = &callout_data;
                    count = pcre_exec(re, extra, (char *)bptr, len, start_offset,
                                      options | g_notempty, use_offsets, use_size_offsets);

                    extra->flags &= ~PCRE_EXTRA_CALLOUT_DATA;
                }
                /* The normal case is just to do the match once, with the default
                value of match_limit. */
                else
                {
                    count = pcre_exec(re, extra, (char *)bptr, len,
                                      start_offset, options | g_notempty, use_offsets, use_size_offsets);
                    if (count == 0)
                    {
                        count = use_size_offsets / 3;
                    }

                    //to retrieve backref count and values
                    if (count > 0 && _pstCapturedString != NULL && _piCapturedStringCount != NULL)
                    {
                        int i = 0;
                        int iErr = 0;

                        iErr = pcre_fullinfo(re, extra, PCRE_INFO_CAPTURECOUNT, _piCapturedStringCount);
                        //sciprint("PCRE_INFO_CAPTURECOUNT %d\n", *_piCapturedStringCount);

                        if (*_piCapturedStringCount > 0)
                        {
                            *_pstCapturedString = (char**)MALLOC(sizeof(char*) * *_piCapturedStringCount);
                            for (i = 0 ; i < *_piCapturedStringCount ; i++)
                            {
                                char* pstSubstring = NULL;
                                pcre_get_substring(bptr, use_offsets, count, i + 1, &pstSubstring);
                                if (pstSubstring != NULL)
                                {
                                    (*_pstCapturedString)[i] = strdup(pstSubstring);
                                }
                                pcre_free_substring(pstSubstring);
                            }
                        }
                    }
                }
                /* Matched */
                if (count >= 0)
                {
                    int i, maxcount;
                    maxcount = use_size_offsets / 3;
                    /* This is a check against a lunatic return value. */
                    if (count > maxcount)
                    {
                        if (buffer)
                        {
                            FREE(buffer);
                            buffer = NULL;
                        }
                        if (offsets)
                        {
                            FREE(offsets);
                            offsets = NULL;
                        }
                        if (re)
                        {
                            (*pcre_free)(re);
                            re = NULL;
                        }
                        if (tables)
                        {
                            (*pcre_free)((void*)tables);
                            tables = NULL;
                        }
                        if (extra)
                        {
                            FREE(extra);
                            extra = NULL;
                        }
                        if (back_p)
                        {
                            FREE(back_p);
                            back_p = NULL;
                        }
                        return TOO_BIG_FOR_OFFSET_SIZE;
                    }

                    for (i = 0; i < count * 2; i += 2)
                    {
                        if (use_offsets[i] >= 0)
                        {
                            *Output_Start = use_offsets[i];
                            *Output_End = use_offsets[i + 1];
                            if (buffer)
                            {
                                FREE(buffer);
                            }

                            /* use_offsets = offsets no need to free use_offsets if we free offsets */
                            if (offsets)
                            {
                                FREE(offsets);
                            }

                            /* "re" allocated by pcre_compile (better to use free function associated)*/
                            if (re)
                            {
                                (*pcre_free)(re);
                            }

                            if (extra)
                            {
                                FREE(extra);
                            }
                            if (tables)
                            {
                                /* "tables" allocated by pcre_maketables (better to use free function associated to pcre)*/
                                (*pcre_free)((void *)tables);
                                tables = NULL;
                                setlocale(LC_CTYPE, "C");
                            }

                            if (back_p)
                            {
                                FREE(back_p);
                                back_p = NULL;
                            }
                            return PCRE_FINISHED_OK;
                        }
                    }

                    for (copynamesptr = copynames; *copynamesptr != 0; copynamesptr += (int)strlen((char*)copynamesptr) + 1)
                    {
                        char copybuffer[256];
                        pcre_copy_named_substring(re, (char *)bptr, use_offsets, count, (char *)copynamesptr, copybuffer, sizeof(copybuffer));
                    }

                    for (i = 0; i < 32; i++)
                    {
                        if ((getstrings & (1 << i)) != 0)
                        {
                            const char *substring;
                            pcre_get_substring((char *)bptr, use_offsets, count, i, &substring);
                        }
                    }

                    for (getnamesptr = getnames; *getnamesptr != 0; getnamesptr += (int)strlen((char*)getnamesptr) + 1)
                    {
                        const char *substring;
                        pcre_get_named_substring(re, (char *)bptr, use_offsets, count, (char *)getnamesptr, &substring);
                    }

                }
                /* Failed to match. If this is a /g or /G loop and we previously set
                g_notempty after a null match, this is not necessarily the end. We want
                to advance the start offset, and continue. We won't be at the end of the
                string - that was checked before setting g_notempty.
                Complication arises in the case when the newline option is "any" or
                "anycrlf". If the previous match was at the end of a line terminated by
                CRLF, an advance of one character just passes the \r, whereas we should
                prefer the longer newline sequence, as does the code in pcre_exec().
                Fudge the offset value to achieve this.

                Otherwise, in the case of UTF-8 matching, the advance must be one
                character, not one byte. */
                else
                {
                    if (count == PCRE_ERROR_NOMATCH)
                    {
                        if (gmatched == 0)
                        {
                            if (tables)
                            {
                                (*pcre_free)((void *)tables);
                                tables = NULL;
                            }
                            if (re)
                            {
                                (*pcre_free)((void *)re);
                                re = NULL;
                            }
                            if (buffer)
                            {
                                FREE(buffer);
                                buffer = NULL;
                            }
                            if (offsets)
                            {
                                FREE(offsets);
                            }
                            if (p)
                            {
                                FREE(back_p);
                                back_p = NULL;
                            }
                            return NO_MATCH;
                        }
                    }

                    if (count == PCRE_ERROR_MATCHLIMIT )
                    {
                        if (tables)
                        {
                            (*pcre_free)((void *)tables);
                            tables = NULL;
                        }
                        if (re)
                        {
                            (*pcre_free)((void *)re);
                            re = NULL;
                        }
                        if (buffer)
                        {
                            FREE(buffer);
                            buffer = NULL;
                        }
                        if (offsets)
                        {
                            FREE(offsets);
                            offsets = NULL;
                        }
                        if (back_p)
                        {
                            FREE(back_p);
                            back_p = NULL;
                        }
                        return MATCH_LIMIT;
                    }
                    break;  /* Out of loop */
                }

                /* If not /g or /G we are done */
                if (!do_g && !do_G)
                {
                    break;
                }

                /* If we have matched an empty string, first check to see if we are at
                the end of the subject. If so, the /g loop is over. Otherwise, mimic
                what Perl's /g options does. This turns out to be rather cunning. First
                we set PCRE_NOTEMPTY and PCRE_ANCHORED and try the match again at the
                same point. If this fails (picked up above) we advance to the next
                character. */

                g_notempty = 0;

                if (use_offsets[0] == use_offsets[1])
                {
                    if (use_offsets[0] == len)
                    {
                        break;
                    }
                    g_notempty = PCRE_NOTEMPTY | PCRE_ANCHORED;
                }

                /* For /g, update the start offset, leaving the rest alone */

                if (do_g)
                {
                    start_offset = use_offsets[1];
                }
                /* For /G, update the pointer and length */
                else
                {
                    bptr += use_offsets[1];
                    len -= use_offsets[1];
                }
            }  /* End of loop for /g and /G */

            if (re)
            {
                (*pcre_free)(re);
                re = NULL;
            }
            if (extra)
            {
                FREE(extra);
                extra = NULL;
            }
            if (tables)
            {
                (*pcre_free)((void *)tables);
                tables = NULL;
            }

            FREE(back_p);
            back_p = NULL;
            continue;
        }    /* End of loop for data lines */
    }

    if (buffer)
    {
        FREE(buffer);
        buffer = NULL;
    }
    if (offsets)
    {
        FREE(offsets);
        offsets = NULL;
    }

    return PCRE_EXIT;
}
Exemple #27
0
int sss_parse_name(TALLOC_CTX *memctx,
                   struct sss_names_ctx *snctx,
                   const char *orig, char **_domain, char **_name)
{
    pcre *re = snctx->re;
    const char *result;
    int ovec[30];
    int origlen;
    int ret, strnum;

    origlen = strlen(orig);

    ret = pcre_exec(re, NULL, orig, origlen, 0, PCRE_NOTEMPTY, ovec, 30);
    if (ret == PCRE_ERROR_NOMATCH) {
        return ERR_REGEX_NOMATCH;
    } else if (ret < 0) {
        DEBUG(SSSDBG_MINOR_FAILURE, "PCRE Matching error, %d\n", ret);
        return EINVAL;
    }

    if (ret == 0) {
        DEBUG(SSSDBG_CRIT_FAILURE,
              "Too many matches, the pattern is invalid.\n");
    }

    strnum = ret;

    if (_name != NULL) {
        result = NULL;
        ret = pcre_get_named_substring(re, orig, ovec, strnum, "name", &result);
        if (ret < 0  || !result) {
            DEBUG(SSSDBG_OP_FAILURE, "Name not found!\n");
            return EINVAL;
        }
        *_name = talloc_strdup(memctx, result);
        pcre_free_substring(result);
        if (!*_name) return ENOMEM;
    }

    if (_domain != NULL) {
        result = NULL;
        ret = pcre_get_named_substring(re, orig, ovec, strnum, "domain",
                                       &result);
        if (ret < 0  || !result) {
            DEBUG(SSSDBG_CONF_SETTINGS, "Domain not provided!\n");
            *_domain = NULL;
        } else {
            /* ignore "" string */
            if (*result) {
                *_domain = talloc_strdup(memctx, result);
                pcre_free_substring(result);
                if (!*_domain) return ENOMEM;
            } else {
                pcre_free_substring(result);
                *_domain = NULL;
            }
        }
    }

    return EOK;
}
Exemple #28
0
// http://www.mitchr.me/SS/exampleCode/AUPG/pcre_example.c.html
static void *gusts_worker(void *data) {
	gusts_results *gr;
	CURL *curl;
	CURLcode res;
	page p;

	char *aStrRegex;
	pcre *reCompiled;
	const char *pcreErrorStr;
	int pcreErrorOffset;
	pcre_extra *pcreExtra;
	int pcreExecRet;
  int subStrVec[30];
  const char *psubStrMatchStr;
  int j;

	gr = data;

	p.len = 0;
	p.capacity = 1024 * sizeof (char);
	p.str = malloc(p.capacity);
	if (!p.str) {
		gr->err = GUSTS_ERR;
		gusts_set_err(gr, "failed to allocate memory for web page data");
		pthread_exit(NULL);
	}

	curl = curl_easy_init();
	if (!curl) {
		gr->err = GUSTS_ERR;
		gusts_set_err(gr, "failed to init curl");
		pthread_exit(NULL);
	}

	curl_easy_setopt(curl, CURLOPT_URL, WEATHER_URL);
	curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, gusts_write_cb);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, &p);
	res = curl_easy_perform(curl);
	if (res != CURLE_OK) {
		gr->err = GUSTS_ERR;
		gusts_set_err(gr, "curl_easy_perform: %s", curl_easy_strerror(res));
		pthread_exit(NULL);
	}
	curl_easy_cleanup(curl);

	//printf("%s\n", p.str);

	aStrRegex = EXPRESSION;

	reCompiled = pcre_compile(aStrRegex, 0, &pcreErrorStr, &pcreErrorOffset, NULL);
	if(!reCompiled) {
	    printf("ERROR: Could not compile '%s': %s\n", aStrRegex, pcreErrorStr);
	    exit(1);
	} /* end if */

	pcreExtra = pcre_study(reCompiled, 0, &pcreErrorStr);

	if(pcreErrorStr != NULL) {
    printf("ERROR: Could not study '%s': %s\n", aStrRegex, pcreErrorStr);
    exit(1);
  } /* end if */

  pcreExecRet = pcre_exec(reCompiled,
                            pcreExtra,
                            p.str,
                            strlen(p.str),  // length of string
                            0,                      // Start looking at this point
                            0,                      // OPTIONS
                            subStrVec,
                            30);                    // Length of subStrVec

	printf("pcreExecRet: %d\n", pcreExecRet);

	// PCRE contains a handy function to do the above for you:
      for(j=0; j<pcreExecRet; j++) {
        pcre_get_substring(p.str, subStrVec, pcreExecRet, j, &(psubStrMatchStr));
        printf("Match(%2d/%2d): (%2d,%2d): '%s'\n", j, pcreExecRet-1, subStrVec[j*2], subStrVec[j*2+1], psubStrMatchStr);
      } /* end for */

      // Free up the substring
      pcre_free_substring(psubStrMatchStr);

	// Free up the regular expression.
  pcre_free(reCompiled);

  // Free up the EXTRA PCRE value (may be NULL at this point)
  if(pcreExtra != NULL)
    pcre_free(pcreExtra);

	gr->err = GUSTS_OK;

	pthread_exit(NULL);
}
Exemple #29
0
static int parse_metar(char *file){
    FILE *fp;
    char *s, *c;
    int ovector[ovecsize];
    int ovalue;
    int len;
    float f;
    int i, j;

    reset_current(&current);
    if((fp=fopen(file, "r"))==NULL) return 0;
    len=fread(bigbuf, sizeof(char), BIGBUF_LEN-2, fp);
    fclose(fp);
    if(len<1) return 0;
    for(i=0; i<len; i++){
        if(isspace(bigbuf[i])) bigbuf[i]=' ';
    }
    c=strstr(bigbuf, " RMK");
    if(c!=NULL) *(c+1)='\0';
    c=strstr(bigbuf, " TEMPO");
    s=strstr(bigbuf, " BECMG");
    if(c!=NULL) *(c+1)='\0';
    if(s!=NULL) *(s+1)='\0';
    /* XXX: parse trend forecast data? */

    len=strlen(bigbuf);
    if(bigbuf[len-1]!=' '){
        bigbuf[len++]=' ';
        bigbuf[len]='\0';
    }

    /* Look for something like a METAR coded report */
    ovalue=pcre_exec(station_time, NULL, bigbuf, len, 0, 0, ovector, ovecsize);
    if(ovalue<=0) return 0;
    if(pcre_get_substring(bigbuf, ovector, ovalue, 1, (const char **)&c)<0) return 0;
    if(c[0]!='\0') current.date=atoi(c);
    pcre_free_substring(c);
    if(pcre_get_substring(bigbuf, ovector, ovalue, 2, (const char **)&c)<0) return 0;
    current.time=atoi(c);
    pcre_free_substring(c);

    /* Chop off extraneous stuff */
    if(pcre_get_substring(bigbuf, ovector, ovalue, 3, (const char **)&s)<0) return 0;

    /* windspeed, winddir */
    ovalue=pcre_exec(wind, NULL, s, len, 0, 0, ovector, ovecsize);
    if(ovalue>0){
        get_substr(4, c);
        if(c[0]!='\0'){
            current.winddir=0;
        } else {
            pcre_free_substring(c);
            get_substr(1, c);
            if(c[0]=='V') current.winddir=0;
            else current.winddir=((int)((atoi(c)+11.25)/22.5))%16+1;
        }
        pcre_free_substring(c);
        get_substr(2, c);
        current.windspeed=atoi(c);
        pcre_free_substring(c);
        get_substr(3, c);
        if(c[0]=='M'){ /* MPS */
            current.windspeed=mps2knots(current.windspeed);
        } else if(c[0]=='K' && c[1]=='M'){ /* KMH */
            current.windspeed=kph2knots(current.windspeed);
        }
    }

    /* vis */
    f=99;
    c=strstr(s, " M1/4SM ");
    if(c!=NULL){
        f=0;
        goto wind_done;
    }
    ovalue=pcre_exec(vis[2], NULL, s, len, 0, 0, ovector, ovecsize);
    if(ovalue>0){
        get_substr(2, c);
        i=atoi(c);
        pcre_free_substring(c);
        get_substr(3, c);
        j=atoi(c);
        pcre_free_substring(c);
        get_substr(1, c);
        f=atoi(c)+(float)i/j;
        pcre_free_substring(c);
        goto wind_done;
    }
    ovalue=pcre_exec(vis[1], NULL, s, len, 0, 0, ovector, ovecsize);
    if(ovalue>0){
        get_substr(2, c);
        i=atoi(c);
        pcre_free_substring(c);
        get_substr(1, c);
        f=(float)atoi(c)/i;
        pcre_free_substring(c);
        goto wind_done;
    }
    ovalue=pcre_exec(vis[0], NULL, s, len, 0, 0, ovector, ovecsize);
    if(ovalue>0){
        get_substr(1, c);
        f=atoi(c);
        pcre_free_substring(c);
        goto wind_done;
    }
    c=strstr(s, " CAVOK ");
    if(c!=NULL){
        f=99;
        current.sky=0;
        goto wind_done;
    }
    ovalue=pcre_exec(vis[3], NULL, s, len, 0, 0, ovector, ovecsize);
    if(ovalue>0){
        get_substr(1, c);
        f=m2mi(atoi(c));
        pcre_free_substring(c);
        goto wind_done;
    }
wind_done:
    if(f<=6) current.vis=6;
    if(f<=5) current.vis=5;
    if(f<3) current.vis=4;
    if(f<1) current.vis=3;
    if(f<=.5) current.vis=2;
    if(f<=.25) current.vis=1;

    /* temp, rh */
    ovalue=pcre_exec(temp, NULL, s, len, 0, 0, ovector, ovecsize);
    if(ovalue>0){
        get_substr(1, c);
        if(c[0]=='M') c[0]='-';
        current.temp=atoi(c);
        pcre_free_substring(c);
        get_substr(2, c);
        if(c[0]!='\0'){
            if(c[0]=='M') c[0]='-';
            current.rh=rh_C(current.temp, atoi(c));
        }
        pcre_free_substring(c);
    }

    /* pressure */
    ovalue=pcre_exec(pressure, NULL, s, len, 0, 0, ovector, ovecsize);
    if(ovalue>0){
        get_substr(2, c);
        i=atoi(c);
        pcre_free_substring(c);
        get_substr(1, c);
        if(c[0]=='Q'){
            current.pressure=hPa2inHg(i);
        } else {
            current.pressure=i/100.0;
        }
        pcre_free_substring(c);
    }

    /* sky */
    if(strstr(s, " SKC")!=NULL || strstr(s, " CLR")!=NULL) current.sky=0;
    if(strstr(s, " FEW")!=NULL) current.sky=1;
    if(strstr(s, " SCT")!=NULL) current.sky=2;
    if(strstr(s, " BKN")!=NULL) current.sky=3;
    if(strstr(s, " OVC")!=NULL || strstr(s, " VV")!=NULL) current.sky=4;

    /* obs, frz, snow, rain, tstorm */
    /* There can be multiple weather chunks, so we while loop */
    j=0;
    while((ovalue=pcre_exec(weather, NULL, s, len, j, 0, ovector, ovecsize))>0){{
        char *in, *de, *pp, *ob, *ot;

        j=ovector[0]+1;
        get_substr(0, c);
        i=(c[1]=='\0');
        pcre_free_substring(c);
        if(i) continue;


        get_substr(1, in);
        get_substr(2, de);
        get_substr(3, pp);
        get_substr(4, ob);
        get_substr(5, ot);

#define IN(haystack, needle) ((needle[0]=='\0')?0:strstr(haystack, needle))
        if(current.obs<1 && strcmp(de, "FZ") && IN("BR|FG", ob))
            current.obs=1;
        if(current.obs<2 && IN("FU|VA|DU|SA|HZ|PY", ob))
            current.obs=2;
        if(current.obs<3 && IN("PO|SS|DS", ot))
            current.obs=3;
        if(current.obs<3 && IN("DR|BL", de)
           && (strstr(pp, "SN") || IN("DU|SA|PY", ob)))
            current.obs=3;
        if(!strcmp(ot, "FC")){
            current.sky=5;
            current.obs=99;
            current.vis=7;
        }
#undef IN

        i=66;
        if(in[0]=='-' || in[0]=='V') i=33;
        if(in[0]=='+') i=99;
        if(!strcmp(de, "SH")) i=33;
        if(current.frz<i
           && ((!strcmp(de, "FZ") && (strstr(pp, "DZ") || strstr(pp, "RA")))
               || strstr(pp, "IC") || strstr(pp, "PE") || strstr(pp, "PL")
               || strstr(pp, "GR") || strstr(pp, "GS")))
                current.frz=i;
        if(current.snow<i && strcmp(de, "BL")
           && (strstr(pp, "SN") || strstr(pp, "SG")))
            current.snow=i;
        if(current.rain<i && (strstr(pp, "UP")
                              || (strcmp(de, "FZ")
                                  && (strstr(pp, "DZ") || strstr(pp, "RA")))))
            current.rain=i;
        if(current.tstorm<i && !strcmp(de, "TS"))
            current.tstorm=i;

        pcre_free_substring(in);
        pcre_free_substring(de);
        pcre_free_substring(pp);
        pcre_free_substring(ob);
        pcre_free_substring(ot);
    }}
    if(current.obs==99) current.obs=0;

    pcre_free_substring(s); /* Done parsing! Just a few final calculations... */

    current.heatindex=heatindex_C(current.temp, current.rh);
    current.windchill=windchill_C(current.temp, current.windspeed);

    /* Figure out the proper month... */
    {
        int mon, day, year, time2; /* holds UTC */
        int y; /* with current.*, holds local time */
        time_t t=time(NULL);
        struct tm *tm=gmtime(&t);
        current.month=tm->tm_mon+1;
        if(tm->tm_mday<current.date) current.month--;
        if(current.month<1){ current.month+=12; tm->tm_year--; }
        y=year=tm->tm_year;
        mon=current.month;
        day=current.date;
        time2=current.time;
        current.time=utc2local((int)current.time, &current.month, &current.date, &y, NULL);

        if(latitude!=999 && calcSolarZenith(latitude, longitude, year, mon, day, hm2min(time2))>90)
            current.moon=calc_moon(current.month, current.date, y, current.time);
    }
    return 1;
}
Exemple #30
0
	__declspec(dllexport) void gen_doc_string(char *func_string,int indentation,char** out)
	{
		pcre *re;
		pcre *re2;
		const char *error;
		int erroffset;
		int ovector[OVECCOUNT];
		int ovector2[OVECCOUNT];
		int rc,rc1;
		std::string doc_string;

		std::string indent_spaces=get_spaces(indentation);

		char *regex="(?P<ret_type>\\w+)\\s+(?P<func_name>\\w+)\\s*\\((?P<func_args>.*)\\)(\\s+(?P<expts_block>throws\\s+(?P<exceptions>.*))|\\s*)";
		re = pcre_compile(
			regex, /* the pattern */
			NULL, /* default options */
			&error, /* for error message */
			&erroffset, /* for error offset */
			NULL); /* use default character table */

		rc=0;
		int offset=0;
		rc = pcre_exec(
			re, /* the compiled pattern */
			NULL, /* no extra data - we didn't study the pattern */
			func_string, /* the subject string */
			strlen(func_string), /* the length of the subject */
			offset, /* start at offset 0 in the subject */
			0, /* default options */
			ovector, /* output vector for substring information */
			OVECCOUNT); /* number of elements in the output
						vector */

		if (rc < 0)
		{
			doc_string.append(indent_spaces);
			doc_string.append("/**\r\n");
			doc_string.append(indent_spaces);
			doc_string.append(" *\r\n");
			doc_string.append(indent_spaces);
			doc_string.append(" *\r\n");
			doc_string.append(indent_spaces);
			doc_string.append(" *\r\n");
			doc_string.append(indent_spaces);
			doc_string.append(" *\r\n");
			doc_string.append(indent_spaces);
			doc_string.append(" *\r\n");
			doc_string.append(indent_spaces);
			doc_string.append(" */\r\n");

			*out=new char[doc_string.size()+1];
			strncpy_s(*out,doc_string.size()+1,doc_string.c_str(),doc_string.size()+1);
			return;
		}

		const char *ret=NULL;
		doc_string.append(indent_spaces);
		doc_string.append("/**\r\n");
		doc_string.append(indent_spaces);
		doc_string.append(" * \r\n");
		doc_string.append(indent_spaces);
		doc_string.append(" * \r\n");


		pcre_get_named_substring(re,func_string,ovector,OVECCOUNT,"func_args",&ret);

		//parse func_args and insert in each line
		char *regex2="(?P<arg_type>\\w+)\\s+(?P<arg_name>\\w+)";
		re2 = pcre_compile(
			regex2, /* the pattern */
			0, /* default options */
			&error, /* for error message */
			&erroffset, /* for error offset */
			NULL); /* use default character table */

		rc1=0;
		int offset1=0;
		rc1 = pcre_exec(
			re2, /* the compiled pattern */
			NULL, /* no extra data - we didn't study the pattern */
			ret, /* the subject string */
			strlen(ret), /* the length of the subject */
			offset1, /* start at offset 0 in the subject */
			0, /* default options */
			ovector2, /* output vector for substring information */
			OVECCOUNT); /* number of elements in the output
						vector */
		if(rc1>0){	
			while(rc1!=-1){

				const char *ret1=NULL;

				pcre_get_named_substring(re2,ret,ovector2,OVECCOUNT,"arg_name",&ret1);
				doc_string.append(indent_spaces);
				doc_string.append(" * @param ");
				doc_string.append(ret1);
				doc_string.append(" \r\n");
				pcre_free_substring(ret1);

				offset1=ovector2[1];

				rc1 = pcre_exec(
					re2, /* the compiled pattern */
					NULL, /* no extra data - we didn't study the pattern */
					ret, /* the subject string */
					strlen(ret), /* the length of the subject */
					offset1, /* start at offset 0 in the subject */
					0, /* default options */
					ovector2, /* output vector for substring information */
					OVECCOUNT); /* number of elements in the output
								vector */

				if (rc1 < 0 || rc < 3)
				{
					break;
				}
			}
		}

		pcre_free_substring(ret);


		//get return type
		pcre_get_named_substring(re,func_string,ovector,OVECCOUNT,"ret_type",&ret);

		if(strcmp(ret,"void")!=0)
		{
			doc_string.append(indent_spaces);
			doc_string.append(" * @return ");
			doc_string.append(ret);
			doc_string.append("\r\n");
		}
		pcre_free_substring(ret);

		//process exceptions block
		pcre_get_named_substring(re,func_string,ovector,OVECCOUNT,"exceptions",&ret);
		if(strlen(ret)>0)
		{
			//function throws exceptions, include in doc string
			char *tmp=new char[strlen(ret)];
			char *next_token;
			strcpy_s(tmp,strlen(ret),ret);
			char *exception_name=strtok_s(tmp,",",&next_token);
			while(exception_name!=NULL)
			{
				std::string s(exception_name);
				trim(&s);
				doc_string.append(indent_spaces);
				doc_string.append(" * @throws ");
				doc_string.append(s);
				doc_string.append("\r\n");
				exception_name=strtok_s(NULL,",",&next_token);
			}
		}

		doc_string.append(indent_spaces);
		doc_string.append(" */\r\n");

		pcre_free(re);
		pcre_free(re2);
		*out=new char[doc_string.size()+1];
		strncpy_s(*out,doc_string.size()+1,doc_string.c_str(),doc_string.size()+1);
		return;
	}