How do I send XML as the email body from a native iPhone app? - iphone

I am writing an app that ultimately wants to send some XML via email.
I have the mailto/URL thing sussed, thanks to various links on the interweb, including Brandon and Simon Maddox.
So I can send emails with the xml formatted using square brackets ([ ]), rather than the usual angle brackets (< >). But when I send angle brackets, with the XML mangled using the stringByAddingPercentEscapesUsingEncoding call, It treats it as HTML and just prints the values.
If change them to "& lt;" and "& gt;" then it totally strips the XML out... (I know there should not be a space after the & - but the SO formatter turns them into <,>...)
I tried adding some HTML in front to see if that helped, to no avail.
I don't suppose anyone has done this?
Perhaps in-app email is the easy route for me to go... must look into that.
Thanks in advance.

The following code worked for me... I have SIP message data containing <> that needed escaping.
/* remember to call urlEscapeStringDone to free the malloced string.. */
char *urlEscapeString(char *str)
{
int i, l;
char *escStr;
escStr = malloc(strlen(str)*3 + 1);
if(!escStr) return NULL;
memset(escStr, 0, strlen(str)*3);
l = strlen(escStr);
for(i = 0; i < strlen(str); i++)
{
char c = str[i];
/* < and > handling for HTML interpreters.. (apple mail) */
if(c == '<')
{
strcat(escStr, "%26lt%3b");
l += 8;
}
else if(c == '>')
{
strcat(escStr, "%26gt%3b");
l += 8;
}
else if(must_escape(c))
{
char tmp[3];
sprintf(tmp, "%02x", (unsigned) c);
escStr[l] = '%'; l++;
escStr[l] = tmp[0]; l++;
escStr[l] = tmp[1]; l++;
}
else
{
escStr[l] = str[i];
l++;
}
}
printf("escaped: %s\n", escStr);
return escStr;
}
void urlEscapeStringDone(char *str)
{
if(str) free(str);
}
int must_escape(char c)
{
char *allowedChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789._";
if(!strchr(allowedChars, c)) return 1;
return 0;
}

Did you try replacing all the '<' and '>' characters with '&lt' and '&gt' after you had wrapped it in the basic HTML headers?
As I understand it, this is the usual technique to display XML on a web page.

Related

Bad address error when comparing Strings within BPF

I have an example program I am running here to see if the substring matches the string and then print them out. So far, I am having trouble running the program due to a bad address. I am wondering if there is a way to fix this problem? I have attached the entire code but my problem is mostly related to isSubstring.
#include <uapi/linux/bpf.h>
#define ARRAYSIZE 64
struct data_t {
char buf[ARRAYSIZE];
};
BPF_ARRAY(lookupTable, struct data_t, ARRAYSIZE);
//char name[20];
//find substring in a string
static bool isSubstring(struct data_t stringVal)
{
char substring[] = "New York";
int M = sizeof(substring);
int N = sizeof(stringVal.buf) - 1;
/* A loop to slide pat[] one by one */
for (int i = 0; i <= N - M; i++) {
int j;
/* For current index i, check for
pattern match */
for (j = 0; j < M; j++)
if (stringVal.buf[i + j] != substring[j])
break;
if (j == M)
return true;
}
return false;
}
int Test(void *ctx)
{
#pragma clang loop unroll(full)
for (int i = 0; i < ARRAYSIZE; i++) {
int k = i;
struct data_t *line = lookupTable.lookup(&k);
if (line) {
// bpf_trace_printk("%s\n", key->buf);
if (isSubstring(*line)) {
bpf_trace_printk("%s\n", line->buf);
}
}
}
return 0;
}
My python code here:
import ctypes
from bcc import BPF
b = BPF(src_file="hello.c")
lookupTable = b["lookupTable"]
#add hello.csv to the lookupTable array
f = open("hello.csv","r")
contents = f.readlines()
for i in range(0,len(contents)):
string = contents[i].encode('utf-8')
print(len(string))
lookupTable[ctypes.c_int(i)] = ctypes.create_string_buffer(string, len(string))
f.close()
b.attach_kprobe(event=b.get_syscall_fnname("clone"), fn_name="Test")
b.trace_print()
Edit: Forgot to add the error: It's really long and can be found here: https://pastebin.com/a7E9L230
I think the most interesting part of the error is near the bottom where it mentions:
The sequence of 8193 jumps is too complex.
And a little bit farther down mentions: Bad Address.
The verifier checks all branches in your program. Each time it sees a jump instruction, it pushes the new branch to its “stack of branches to check”. This stack has a limit (BPF_COMPLEXITY_LIMIT_JMP_SEQ, currently 8192) that you are hitting, as the verifier tells you. “Bad Address” is just the translation of kernel's errno value which is set to -EFAULT in that case.
Not sure how to fix it though, you could try:
With smaller strings, or
On a 5.3+ kernel (which supports bounded loops): without unrolling the loop with clang (I don't know if it would help).

Generating DXL documentation using Doxygen : if is shown as a function

I am trying to generate some DXL documentation usings Doxygen , but the results are often not correct , DXL is used as a scripting language and that has a C/C++ like syntax with some changes , like for example i can ignor using the Semicolons , What should i do to correct this problem ?
which creates some problems while generating the documentation, here is an example of my dxl code database :
string replace (string sSource, string sSearch, string sReplace) {
int iLen = length sSource
if (iLen == 0) return ""
int iLenSearch = length(sSearch)
if (iLenSearch == 0) {
return ""
}
char firstChar = sSearch[0]
Buffer s = create()
int pos = 0, d1,d2;
int i
while (pos < iLen) {
char ch = sSource[pos];
bool found = true
if (ch != firstChar) {pos ++; s+= ch; continue}
for (i = 1; i < iLenSearch; i++) {
if (sSource[pos+i] != sSearch[i]) { found = false; break }
}
if (!found) {pos++; s+= ch; continue}
s += sReplace
pos += iLenSearch
}
string result = stringOf s
delete s
return result }
as i said the main difference with C and that may cause doxygen to interpret this code incorrectly is that in DXL , we dont have to use ";" .
thanks in advance
You must do three things to apply Doxygen successfully on DXL scripts:
1.) In Doxygen-GUI, 'Wizard' tab, section 'Mode' choose 'Optimize for C or PHP'
2.) The DXL code must be C-confom, i.e. each statement ends with a semicolon ';'
3.) In tab 'Expert' set language mapping for DXL and INC files in section 'Project' under 'EXTENSION_MAPPING':
dxl=C
inc=C
This all tells Doxygen to treat DXL scripts as C code.
Further, for DOORS to recognize a DXL file documented for DoxyGen as valid and bind it to a menu item, it must comply with certain header structure, consisting of single line and multi-line comment, e.g.
// <dxl-file>
/**
* #file <dxl-file>
* #copyright (c) ...
* #author Th. Grosser
* #date 01 Dec 2017
* #brief ...
*/

How to make 'ő' and 'ű' work in Java?

String word = inputField.getText();
int wordLength = word.length();
boolean backWord = false;
boolean longWord = false;
String backArray[]=new String[6];
backArray[0] = "a";
backArray[1] = "á";
backArray[2] = "ö";
backArray[3] = "ő";
backArray[4] = "ü";
backArray[5] = "ű";
for (int i = 0;i < wordLength ;i ++ ) {
String character = word.substring(i, i + 1);
for (int j = 0;j < 5;j ++) {
if (character.equals(backArray[j])) {
backWord = true;
}
}
}
if (backWord) {
outputField.setText(word+"ban");
}
else {
outputField.setText(word+"ben");
}
This is the code I wrote for an applet for conjugating Hungarian nouns while taking vowel harmony into consideration. For the unaware, the TL;DR of vowel harmony is that Hungarian has lots of suffixes and you can determine which suffix to use based on the vowels in a word.
This code works fine for all the vowels, except for ő and ű. So if my input is 'szálloda', the output will be 'szállodaban'. However, if my input is 'idő' (weather) the output will be 'időben', though it should be 'időban' according to the code.
I assumed this is because java somehow doesn't recognize these two letters because the code works fine for the other ones. Is that the problem? And if so, how do I solve it?

PostgreSQL clarification

I have written a function inside PostgreSQL which has the following code:
for (i = 0; i < 4; i++)
{
Datum dat_value = CStringGetDatum(inp->str[0][i]);
values[i] = datumCopy(dat_value,
stats->attrtype->typbyval,
stats->attrtype->typlen);
}
The input strings are {ALGERIA,ARGENTINA,BRAZIL,CANADA}. The code runs for ALGERIA,ARGENTINA but terminates abruptly for BRAZIL. When I investigated I found that inside datumCopy function, the statement after memcpy is not getting printed. I checked if palloc failed with (s == NULL) condition, but that seems to be not the reason. I think memcpy is failing. Any reason why? Thanks!
Datum
datumCopy(Datum value, bool typByVal, int typLen)
{
Datum res;
if (typByVal)
res = value;
else
{
Size realSize;
char *s;
if (DatumGetPointer(value) == NULL)
return PointerGetDatum(NULL);
realSize = datumGetSize(value, typByVal, typLen);
s = (char *) palloc(realSize);
printf ("Value : %s\n",DatumGetPointer(value));
memcpy(s, DatumGetPointer(value), realSize);
printf ("Not printing \n");
res = PointerGetDatum(s);
}
return res;
}
EDITED : Ok this is really wierd. When the input is one of {BRAZIL,PAKISTAN,FRANCE}, the code terminates abruptly. If I have other countries (I haven't tried extensively, but some countries), the code runs correctly.
EDITED 2 : Found the cause and rectified the issue. If we are passing C strings to datumCopy, we have to pass -2 for typLen parameter. I had been passing it incorrectly.
Thanks!
I have found the cause and rectified the issue.
If we are passing C strings to datumCopy, we have to pass -2 for typLen parameter. I had been passing it incorrectly.

Parsing email "Received:" headers

We need to parse Received: email headers according to RFC 5321. We need to extract domains or IPs through which the mail has traversed. Also, we need to figure out if an IP is an internal IP.
Is there already a library which can help out, preferably in C\C++?
For example:
Received: from server.mymailhost.com (mail.mymailhost.com [126.43.75.123])
by pilot01.cl.msu.edu (8.10.2/8.10.2) with ESMTP id NAA23597;
Fri, 12 Jul 2002 16:11:20 -0400 (EDT)
We need to extract the "by" server.
The format used by 'Received' lines is defined in RFC 2821, and regex can't parse it.
(You can try anyway, and for a limited subset of headers produced by known software you might succeed, but when you attach this to the range of strange stuff found in real-world mail it will fail.)
Use an existing RFC 2821 parser and you should be OK, but otherwise you should expect failure, and write the software to cope with it. Don't base anything important like a security system around it.
We need to extract the "by" server.
'from' is more likely to be of use. The hostname given in a 'by' line is as seen by the host itself, so there is no guarantee it will be a publically resolvable FQDN. And of course you don't tend to get valid (TCP-Info) there.
There is a Perl Received module which is a fork of the SpamAssassin code. It returns a hash for a Received header with the relevant information. For example
{ ip => '64.12.136.4',
id => '875522',
by => 'xxx.com',
helo => 'imo-m01.mx.aol.com' }
vmime should be fine, moreless any mail library will allow you to do that.
You'll want to use Regular Expressions possibly
(?<=by).*(?=with)
This will give you pilot01.cl.msu.edu (8.10.2/8.10.2)
Edit:
I find it amusing that this was modded down when it actually gets what the OP asked for.
C#:
string header = "Received: from server.mymailhost.com (mail.mymailhost.com [126.43.75.123]) by pilot01.cl.msu.edu (8.10.2/8.10.2) with ESMTP id NAA23597; Fri, 12 Jul 2002 16:11:20 -0400 (EDT)";
System.Text.RegularExpressions.Regex r = new System.Text.RegularExpressions.Regex(#"(?<=by).*(?=with)");
System.Text.RegularExpressions.Match m = r.Match(header);
Console.WriteLine(m.Captures[0].Value);
Console.ReadKey();
I didnt claim that it was complete, but am wondering if the person that gave it a -1 even tried. Meh..
You can use regular expressions. It would look like this(not tested):
#include <regex.h>
regex_t *re = malloc(sizeof(regex_t));
const char *restr = "by ([A-Za-z.]+) \(([^\)]*)\)";
check(regcomp(re, restr, REG_EXTENDED | REG_ICASE), "regcomp");
size_t nmatch = 1;
regmatch_t *matches = malloc(sizeof(regmatch_t) * nmatch);
int ret = regexec(re, YOUR_STRING, nmatch, matches, 0);
check(ret != 0, "regexec");
int size;
size = matches[2].rm_eo - matches[2].rm_so;
char *host = malloc(sizeof(char) * size);
strncpy(host, YOUR_STRING + matches[2].rm_so, size );
host[size] = '\0';
size = matches[3].rm_eo - matches[3].rm_so;
char *ip = malloc(sizeof(char) * size);
strncpy(ip, YOUR_STRING + matches[3].rm_so, size );
ip[size] = '\0';
check is a macro to help you figure out if there are any problems:
#define check(condition, description) if (condition) { fprintf(stdout, "%s:%i - %s - %s\n", __FILE__, __LINE__, description, strerror(errno)); exit(1); }
typedef struct mailHeaders{
char name[100];
char value[2000];
}mailHeaders;
int header_count = 0;
mailHeaders headers[30]; // A struct to hold the name value pairs
char *GetMailHeader(char *name)
{
char *value = NULL;;
int i;
for(i=0;i<header_count;i++){
if(strcmp(name,headers[i].name) == 0){
value = headers[i].value;
break;
}
}
return(value);
}
void ReadMail(void)
{
//Loop through the email message line by line to separate the headers. Then save the name value pairs to a linked list or struct.
char *Received = NULL // Received header
char *mail = NULL; // Buffer that has the email message.
char *line = NULL; // A line of text in the email.
char *name = NULL; // Header name
char *value = NULL; // Header value
int index = -1; // Header index
memset(&headers,'\0',sizeof(mailHeaders));
line = strtok(mail,"\n");
while(line != NULL)
{
if(*line == '\t') // Tabbed headers
{
strcat(headers[index].value,line); // Concatenate the tabbed values
}
else
{
name = line;
value = strchr(line,':'); // Split the name value pairs.
if(value != NULL)
{
*value='\0'; // NULL the colon
value++; // Move the pointer past the NULL character to separate the name and value
index++;
strcpy(headers[index].name,name); // Copy the name to the data structure
strcpy(headers[index].value,value); // Copy the value to the data structure
}
}
if(*line == '\r') // End of headers
break;
line = strtok(NULL,"\n"); // Get next header
header_count = index;
}
Received = GetMailHeader("Received");
}
It is not difficult to parse such headers, even manually line-by-line. A regex could help there by looking at by\s+(\w)+\(. For C++, you could try that library or that one.
Have you considered using regular expressions?
Here is a list of internal, non-routable address ranges.