/****************************************************************************** * Processes a registry file. * Correctly processes comments (in # and ; form), line continuation. * * Parameters: * in - input stream to read from * first_chars - beginning of stream, read due to Unicode check */ static void processRegLinesA(FILE *in, char* first_chars) { LPSTR line = NULL; /* line read from input stream */ ULONG lineSize = REG_VAL_BUF_SIZE; line = HeapAlloc(GetProcessHeap(), 0, lineSize); CHECK_ENOUGH_MEMORY(line); memcpy(line, first_chars, 2); while (!feof(in)) { LPSTR s; /* The pointer into line for where the current fgets should read */ WCHAR* lineW; s = line; if(first_chars) { s += 2; first_chars = NULL; } for (;;) { size_t size_remaining; int size_to_get, i; char *s_eol; /* various local uses */ /* Do we need to expand the buffer ? */ assert (s >= line && s <= line + lineSize); size_remaining = lineSize - (s-line); if (size_remaining < 2) /* room for 1 character and the \0 */ { char *new_buffer; size_t new_size = lineSize + REG_VAL_BUF_SIZE; if (new_size > lineSize) /* no arithmetic overflow */ new_buffer = HeapReAlloc (GetProcessHeap(), 0, line, new_size); else new_buffer = NULL; CHECK_ENOUGH_MEMORY(new_buffer); line = new_buffer; s = line + lineSize - size_remaining; lineSize = new_size; size_remaining = lineSize - (s-line); } /* Get as much as possible into the buffer, terminated either by * eof, error, eol or getting the maximum amount. Abort on error. */ size_to_get = (size_remaining > INT_MAX ? INT_MAX : size_remaining); /* get a single line. note that `i' must be one past the last * meaningful character in `s' when this loop exits */ for(i = 0; i < size_to_get-1; ++i){ int xchar; xchar = fgetc(in); s[i] = xchar; if(xchar == EOF){ if(ferror(in)){ perror("While reading input"); exit(IO_ERROR); }else assert(feof(in)); break; } if(s[i] == '\r'){ /* read the next character iff it's \n */ if(i+2 >= size_to_get){ /* buffer too short, so put back the EOL char to * read next cycle */ ungetc('\r', in); break; } s[i+1] = fgetc(in); if(s[i+1] != '\n'){ ungetc(s[i+1], in); i = i+1; }else i = i+2; break; } if(s[i] == '\n'){ i = i+1; break; } } s[i] = '\0'; /* If we didn't read the eol nor the eof go around for the rest */ s_eol = strpbrk (s, "\r\n"); if (!feof (in) && !s_eol) { s = strchr (s, '\0'); continue; } /* If it is a comment line then discard it and go around again */ if (line [0] == '#' || line [0] == ';') { s = line; continue; } /* Remove any line feed. Leave s_eol on the first \0 */ if (s_eol) { if (*s_eol == '\r' && *(s_eol+1) == '\n') *(s_eol+1) = '\0'; *s_eol = '\0'; } else s_eol = strchr (s, '\0'); /* If there is a concatenating \\ then go around again */ if (s_eol > line && *(s_eol-1) == '\\') { int c; s = s_eol-1; do { c = fgetc(in); } while(c == ' ' || c == '\t'); if(c == EOF) { fprintf(stderr,"%s: ERROR - invalid continuation.\n", getAppName()); } else { *s = c; s++; } continue; } lineW = GetWideString(line); break; /* That is the full virtual line */ } processRegEntry(lineW, FALSE); HeapFree(GetProcessHeap(), 0, lineW); } processRegEntry(NULL, FALSE); HeapFree(GetProcessHeap(), 0, line); }
static void processRegLinesW(FILE *in) { WCHAR* buf = NULL; /* line read from input stream */ ULONG lineSize = REG_VAL_BUF_SIZE; size_t CharsInBuf = -1; WCHAR* s; /* The pointer into buf for where the current fgets should read */ WCHAR* line; /* The start of the current line */ buf = HeapAlloc(GetProcessHeap(), 0, lineSize * sizeof(WCHAR)); CHECK_ENOUGH_MEMORY(buf); s = buf; line = buf; while(!feof(in)) { size_t size_remaining; int size_to_get; WCHAR *s_eol = NULL; /* various local uses */ /* Do we need to expand the buffer ? */ assert (s >= buf && s <= buf + lineSize); size_remaining = lineSize - (s-buf); if (size_remaining < 2) /* room for 1 character and the \0 */ { WCHAR *new_buffer; size_t new_size = lineSize + (REG_VAL_BUF_SIZE / sizeof(WCHAR)); if (new_size > lineSize) /* no arithmetic overflow */ new_buffer = HeapReAlloc (GetProcessHeap(), 0, buf, new_size * sizeof(WCHAR)); else new_buffer = NULL; CHECK_ENOUGH_MEMORY(new_buffer); buf = new_buffer; line = buf; s = buf + lineSize - size_remaining; lineSize = new_size; size_remaining = lineSize - (s-buf); } /* Get as much as possible into the buffer, terminated either by * eof, error or getting the maximum amount. Abort on error. */ size_to_get = (size_remaining > INT_MAX ? INT_MAX : size_remaining); CharsInBuf = fread(s, sizeof(WCHAR), size_to_get - 1, in); s[CharsInBuf] = 0; if (CharsInBuf == 0) { if (ferror(in)) { perror ("While reading input"); exit (IO_ERROR); } else { assert (feof(in)); *s = '\0'; /* It is not clear to me from the definition that the * contents of the buffer are well defined on detecting * an eof without managing to read anything. */ } } /* If we didn't read the eol nor the eof go around for the rest */ while(1) { const WCHAR line_endings[] = {'\r','\n',0}; s_eol = strpbrkW(line, line_endings); if(!s_eol) { /* Move the stub of the line to the start of the buffer so * we get the maximum space to read into, and so we don't * have to recalculate 'line' if the buffer expands */ MoveMemory(buf, line, (strlenW(line)+1) * sizeof(WCHAR)); line = buf; s = strchrW(line, '\0'); break; } /* If it is a comment line then discard it and go around again */ if (*line == '#' || *line == ';') { if (*s_eol == '\r' && *(s_eol+1) == '\n') line = s_eol + 2; else line = s_eol + 1; continue; } /* If there is a concatenating \\ then go around again */ if (*(s_eol-1) == '\\') { WCHAR* NextLine = s_eol + 1; if(*s_eol == '\r' && *(s_eol+1) == '\n') NextLine++; while(*(NextLine+1) == ' ' || *(NextLine+1) == '\t') NextLine++; MoveMemory(s_eol - 1, NextLine, (CharsInBuf - (NextLine - s) + 1)*sizeof(WCHAR)); CharsInBuf -= NextLine - s_eol + 1; s_eol = 0; continue; } /* Remove any line feed. Leave s_eol on the last \0 */ if (*s_eol == '\r' && *(s_eol + 1) == '\n') *s_eol++ = '\0'; *s_eol = '\0'; processRegEntry(line, TRUE); line = s_eol + 1; s_eol = 0; continue; /* That is the full virtual line */ } } processRegEntry(NULL, TRUE); HeapFree(GetProcessHeap(), 0, buf); }
/****************************************************************************** * Processes a registry file. * Correctly processes comments (in # and ; form), line continuation. * * Parameters: * in - input stream to read from * first_chars - beginning of stream, read due to Unicode check */ static void processRegLinesA(FILE *in, char* first_chars) { char *buf = NULL; /* the line read from the input stream */ unsigned long line_size = REG_VAL_BUF_SIZE; size_t chars_in_buf = -1; char *s; /* A pointer to buf for fread */ char *line; /* The start of the current line */ WCHAR *lineW; buf = HeapAlloc(GetProcessHeap(), 0, line_size); CHECK_ENOUGH_MEMORY(buf); s = buf; line = buf; memcpy(line, first_chars, 2); if (first_chars) s += 2; while (!feof(in)) { size_t size_remaining; int size_to_get; char *s_eol = NULL; /* various local uses */ /* Do we need to expand the buffer? */ assert(s >= buf && s <= buf + line_size); size_remaining = line_size - (s - buf); if (size_remaining < 3) /* we need at least 3 bytes of room for \r\n\0 */ { char *new_buffer; size_t new_size = line_size + REG_VAL_BUF_SIZE; if (new_size > line_size) /* no arithmetic overflow */ new_buffer = HeapReAlloc(GetProcessHeap(), 0, buf, new_size); else new_buffer = NULL; CHECK_ENOUGH_MEMORY(new_buffer); buf = new_buffer; line = buf; s = buf + line_size - size_remaining; line_size = new_size; size_remaining = line_size - (s - buf); } /* Get as much as possible into the buffer, terminating on EOF, * error or once we have read the maximum amount. Abort on error. */ size_to_get = (size_remaining > INT_MAX ? INT_MAX : size_remaining); chars_in_buf = fread(s, 1, size_to_get - 1, in); s[chars_in_buf] = 0; if (chars_in_buf == 0) { if (ferror(in)) { perror("While reading input"); exit(IO_ERROR); } else { assert(feof(in)); *s = '\0'; } } /* If we didn't read the end-of-line sequence or EOF, go around again */ while (1) { s_eol = strpbrk(line, "\r\n"); if (!s_eol) { /* Move the stub of the line to the start of the buffer so * we get the maximum space to read into, and so we don't * have to recalculate 'line' if the buffer expands */ MoveMemory(buf, line, strlen(line) + 1); line = buf; s = strchr(line, '\0'); break; } /* If we find a comment line, discard it and go around again */ if (line [0] == '#' || line [0] == ';') { if (*s_eol == '\r' && *(s_eol + 1) == '\n') line = s_eol + 2; else line = s_eol + 1; continue; } /* If there is a concatenating '\\', go around again */ if (*(s_eol - 1) == '\\') { char *next_line = s_eol + 1; if (*s_eol == '\r' && *(s_eol + 1) == '\n') next_line++; while (*(next_line + 1) == ' ' || *(next_line + 1) == '\t') next_line++; MoveMemory(s_eol - 1, next_line, chars_in_buf - (next_line - s) + 1); chars_in_buf -= next_line - s_eol + 1; s_eol = 0; continue; } /* Remove any line feed. Leave s_eol on the last \0 */ if (*s_eol == '\r' && *(s_eol + 1) == '\n') *s_eol++ = '\0'; *s_eol = '\0'; lineW = GetWideString(line); processRegEntry(lineW, FALSE); HeapFree(GetProcessHeap(), 0, lineW); line = s_eol + 1; s_eol = 0; continue; /* That is the full virtual line */ } } processRegEntry(NULL, FALSE); HeapFree(GetProcessHeap(), 0, buf); }