Morpheme * analyse_decomposed_word(Morpho_structures ms, Decomposed_word *decomposed_word){ Sentence sent; Linkage linkage; Decomposed_word *node; Morpheme *morpheme_list=NULL; int num_linkages , i; int stem_pos; char * diagram; // ms->opts->unify_features = FALSE; for(node=decomposed_word; node!=NULL; node=node->next){ sent=sentence_create(node->word, ms->dict); if(!sent){ continue; } num_linkages = sentence_parse(sent, ms->opts); for (i=0; i<num_linkages; i++){ linkage = linkage_create(i, sent, ms->opts); if (PRINT_DIAGRAM){ linkage = linkage_create(i, sent, ms->opts); printf("%s\n", diagram = linkage_print_diagram(linkage)); string_delete(diagram); } if ((stem_pos = find_stem(linkage))>=0){ morpheme_list_add(ms, &morpheme_list,linkage->word[stem_pos], linkage->feature_array[0]); } linkage_delete(linkage); } sentence_delete(sent); } return morpheme_list; }
static int load_mmap(struct selabel_handle *rec, const char *path, struct stat *sb) { struct saved_data *data = (struct saved_data *)rec->data; char mmap_path[PATH_MAX + 1]; int mmapfd; int rc; struct stat mmap_stat; char *addr, *str_buf; size_t len; int *stem_map; struct mmap_area *mmap_area; uint32_t i, magic, version; uint32_t entry_len, stem_map_len, regex_array_len; rc = snprintf(mmap_path, sizeof(mmap_path), "%s.bin", path); if (rc >= (int)sizeof(mmap_path)) return -1; mmapfd = open(mmap_path, O_RDONLY | O_CLOEXEC); if (mmapfd < 0) return -1; rc = fstat(mmapfd, &mmap_stat); if (rc < 0) { close(mmapfd); return -1; } /* if mmap is old, ignore it */ if (mmap_stat.st_mtime < sb->st_mtime) { close(mmapfd); return -1; } /* ok, read it in... */ len = mmap_stat.st_size; len += (sysconf(_SC_PAGE_SIZE) - 1); len &= ~(sysconf(_SC_PAGE_SIZE) - 1); mmap_area = malloc(sizeof(*mmap_area)); if (!mmap_area) { close(mmapfd); return -1; } addr = mmap(NULL, len, PROT_READ, MAP_PRIVATE, mmapfd, 0); close(mmapfd); if (addr == MAP_FAILED) { free(mmap_area); perror("mmap"); return -1; } /* save where we mmap'd the file to cleanup on close() */ mmap_area->addr = addr; mmap_area->len = len; mmap_area->next = data->mmap_areas; data->mmap_areas = mmap_area; /* check if this looks like an fcontext file */ rc = next_entry(&magic, mmap_area, sizeof(uint32_t)); if (rc < 0 || magic != SELINUX_MAGIC_COMPILED_FCONTEXT) return -1; /* check if this version is higher than we understand */ rc = next_entry(&version, mmap_area, sizeof(uint32_t)); if (rc < 0 || version > SELINUX_COMPILED_FCONTEXT_MAX_VERS) return -1; if (version >= SELINUX_COMPILED_FCONTEXT_PCRE_VERS) { len = strlen(pcre_version()); rc = next_entry(&entry_len, mmap_area, sizeof(uint32_t)); if (rc < 0) return -1; /* Check version lengths */ if (len != entry_len) return -1; /* Check if pcre version mismatch */ str_buf = malloc(entry_len + 1); if (!str_buf) return -1; rc = next_entry(str_buf, mmap_area, entry_len); if (rc < 0) { free(str_buf); return -1; } str_buf[entry_len] = '\0'; if ((strcmp(str_buf, pcre_version()) != 0)) { free(str_buf); return -1; } free(str_buf); } /* allocate the stems_data array */ rc = next_entry(&stem_map_len, mmap_area, sizeof(uint32_t)); if (rc < 0 || !stem_map_len) return -1; /* * map indexed by the stem # in the mmap file and contains the stem * number in the data stem_arr */ stem_map = calloc(stem_map_len, sizeof(*stem_map)); if (!stem_map) return -1; for (i = 0; i < stem_map_len; i++) { char *buf; uint32_t stem_len; int newid; /* the length does not inlude the nul */ rc = next_entry(&stem_len, mmap_area, sizeof(uint32_t)); if (rc < 0 || !stem_len) { rc = -1; goto err; } /* Check for stem_len wrap around. */ if (stem_len < UINT32_MAX) { buf = (char *)mmap_area->addr; /* Check if over-run before null check. */ rc = next_entry(NULL, mmap_area, (stem_len + 1)); if (rc < 0) goto err; if (buf[stem_len] != '\0') { rc = -1; goto err; } } else { rc = -1; goto err; } /* store the mapping between old and new */ newid = find_stem(data, buf, stem_len); if (newid < 0) { newid = store_stem(data, buf, stem_len); if (newid < 0) { rc = newid; goto err; } data->stem_arr[newid].from_mmap = 1; } stem_map[i] = newid; } /* allocate the regex array */ rc = next_entry(®ex_array_len, mmap_area, sizeof(uint32_t)); if (rc < 0 || !regex_array_len) { rc = -1; goto err; } for (i = 0; i < regex_array_len; i++) { struct spec *spec; int32_t stem_id, meta_chars; uint32_t mode = 0, prefix_len = 0; rc = grow_specs(data); if (rc < 0) goto err; spec = &data->spec_arr[data->nspec]; spec->from_mmap = 1; spec->regcomp = 1; /* Process context */ rc = next_entry(&entry_len, mmap_area, sizeof(uint32_t)); if (rc < 0 || !entry_len) { rc = -1; goto err; } str_buf = malloc(entry_len); if (!str_buf) { rc = -1; goto err; } rc = next_entry(str_buf, mmap_area, entry_len); if (rc < 0) goto err; if (str_buf[entry_len - 1] != '\0') { free(str_buf); rc = -1; goto err; } spec->lr.ctx_raw = str_buf; /* Process regex string */ rc = next_entry(&entry_len, mmap_area, sizeof(uint32_t)); if (rc < 0 || !entry_len) { rc = -1; goto err; } spec->regex_str = (char *)mmap_area->addr; rc = next_entry(NULL, mmap_area, entry_len); if (rc < 0) goto err; if (spec->regex_str[entry_len - 1] != '\0') { rc = -1; goto err; } /* Process mode */ if (version >= SELINUX_COMPILED_FCONTEXT_MODE) rc = next_entry(&mode, mmap_area, sizeof(uint32_t)); else rc = next_entry(&mode, mmap_area, sizeof(mode_t)); if (rc < 0) goto err; spec->mode = mode; /* map the stem id from the mmap file to the data->stem_arr */ rc = next_entry(&stem_id, mmap_area, sizeof(int32_t)); if (rc < 0) goto err; if (stem_id < 0 || stem_id >= (int32_t)stem_map_len) spec->stem_id = -1; else spec->stem_id = stem_map[stem_id]; /* retrieve the hasMetaChars bit */ rc = next_entry(&meta_chars, mmap_area, sizeof(uint32_t)); if (rc < 0) goto err; spec->hasMetaChars = meta_chars; /* and prefix length for use by selabel_lookup_best_match */ if (version >= SELINUX_COMPILED_FCONTEXT_PREFIX_LEN) { rc = next_entry(&prefix_len, mmap_area, sizeof(uint32_t)); if (rc < 0) goto err; spec->prefix_len = prefix_len; } /* Process regex and study_data entries */ rc = next_entry(&entry_len, mmap_area, sizeof(uint32_t)); if (rc < 0 || !entry_len) { rc = -1; goto err; } spec->regex = (pcre *)mmap_area->addr; rc = next_entry(NULL, mmap_area, entry_len); if (rc < 0) goto err; /* Check that regex lengths match. pcre_fullinfo() * also validates its magic number. */ rc = pcre_fullinfo(spec->regex, NULL, PCRE_INFO_SIZE, &len); if (rc < 0 || len != entry_len) { rc = -1; goto err; } rc = next_entry(&entry_len, mmap_area, sizeof(uint32_t)); if (rc < 0 || !entry_len) { rc = -1; goto err; } spec->lsd.study_data = (void *)mmap_area->addr; spec->lsd.flags |= PCRE_EXTRA_STUDY_DATA; rc = next_entry(NULL, mmap_area, entry_len); if (rc < 0) goto err; /* Check that study data lengths match. */ rc = pcre_fullinfo(spec->regex, &spec->lsd, PCRE_INFO_STUDYSIZE, &len); if (rc < 0 || len != entry_len) { rc = -1; goto err; } data->nspec++; } /* win */ rc = 0; err: free(stem_map); return rc; }
static int load_mmap(FILE *fp, size_t len, struct selabel_handle *rec, const char *path) { struct saved_data *data = (struct saved_data *)rec->data; int rc; char *addr, *str_buf; int *stem_map; struct mmap_area *mmap_area; uint32_t i, magic, version; uint32_t entry_len, stem_map_len, regex_array_len; const char *reg_version; const char *reg_arch; char reg_arch_matches = 0; mmap_area = malloc(sizeof(*mmap_area)); if (!mmap_area) { return -1; } addr = mmap(NULL, len, PROT_READ, MAP_PRIVATE, fileno(fp), 0); if (addr == MAP_FAILED) { free(mmap_area); perror("mmap"); return -1; } /* save where we mmap'd the file to cleanup on close() */ mmap_area->addr = mmap_area->next_addr = addr; mmap_area->len = mmap_area->next_len = len; mmap_area->next = data->mmap_areas; data->mmap_areas = mmap_area; /* check if this looks like an fcontext file */ rc = next_entry(&magic, mmap_area, sizeof(uint32_t)); if (rc < 0 || magic != SELINUX_MAGIC_COMPILED_FCONTEXT) return -1; /* check if this version is higher than we understand */ rc = next_entry(&version, mmap_area, sizeof(uint32_t)); if (rc < 0 || version > SELINUX_COMPILED_FCONTEXT_MAX_VERS) return -1; reg_version = regex_version(); if (!reg_version) return -1; reg_arch = regex_arch_string(); if (!reg_arch) return -1; if (version >= SELINUX_COMPILED_FCONTEXT_PCRE_VERS) { len = strlen(reg_version); rc = next_entry(&entry_len, mmap_area, sizeof(uint32_t)); if (rc < 0) return -1; /* Check version lengths */ if (len != entry_len) return -1; /* Check if regex version mismatch */ str_buf = malloc(entry_len + 1); if (!str_buf) return -1; rc = next_entry(str_buf, mmap_area, entry_len); if (rc < 0) { free(str_buf); return -1; } str_buf[entry_len] = '\0'; if ((strcmp(str_buf, reg_version) != 0)) { free(str_buf); return -1; } free(str_buf); if (version >= SELINUX_COMPILED_FCONTEXT_REGEX_ARCH) { len = strlen(reg_arch); rc = next_entry(&entry_len, mmap_area, sizeof(uint32_t)); if (rc < 0) return -1; /* Check arch string lengths */ if (len != entry_len) { /* * Skip the entry and conclude that we have * a mismatch, which is not fatal. */ next_entry(NULL, mmap_area, entry_len); goto end_arch_check; } /* Check if arch string mismatch */ str_buf = malloc(entry_len + 1); if (!str_buf) return -1; rc = next_entry(str_buf, mmap_area, entry_len); if (rc < 0) { free(str_buf); return -1; } str_buf[entry_len] = '\0'; reg_arch_matches = strcmp(str_buf, reg_arch) == 0; free(str_buf); } } end_arch_check: /* allocate the stems_data array */ rc = next_entry(&stem_map_len, mmap_area, sizeof(uint32_t)); if (rc < 0) return -1; /* * map indexed by the stem # in the mmap file and contains the stem * number in the data stem_arr */ stem_map = calloc(stem_map_len, sizeof(*stem_map)); if (!stem_map) return -1; for (i = 0; i < stem_map_len; i++) { char *buf; uint32_t stem_len; int newid; /* the length does not inlude the nul */ rc = next_entry(&stem_len, mmap_area, sizeof(uint32_t)); if (rc < 0 || !stem_len) { rc = -1; goto out; } /* Check for stem_len wrap around. */ if (stem_len < UINT32_MAX) { buf = (char *)mmap_area->next_addr; /* Check if over-run before null check. */ rc = next_entry(NULL, mmap_area, (stem_len + 1)); if (rc < 0) goto out; if (buf[stem_len] != '\0') { rc = -1; goto out; } } else { rc = -1; goto out; } /* store the mapping between old and new */ newid = find_stem(data, buf, stem_len); if (newid < 0) { newid = store_stem(data, buf, stem_len); if (newid < 0) { rc = newid; goto out; } data->stem_arr[newid].from_mmap = 1; } stem_map[i] = newid; } /* allocate the regex array */ rc = next_entry(®ex_array_len, mmap_area, sizeof(uint32_t)); if (rc < 0 || !regex_array_len) { rc = -1; goto out; } for (i = 0; i < regex_array_len; i++) { struct spec *spec; int32_t stem_id, meta_chars; uint32_t mode = 0, prefix_len = 0; rc = grow_specs(data); if (rc < 0) goto out; spec = &data->spec_arr[data->nspec]; spec->from_mmap = 1; /* Process context */ rc = next_entry(&entry_len, mmap_area, sizeof(uint32_t)); if (rc < 0 || !entry_len) { rc = -1; goto out; } str_buf = malloc(entry_len); if (!str_buf) { rc = -1; goto out; } rc = next_entry(str_buf, mmap_area, entry_len); if (rc < 0) { free(str_buf); goto out; } if (str_buf[entry_len - 1] != '\0') { free(str_buf); rc = -1; goto out; } spec->lr.ctx_raw = str_buf; if (strcmp(spec->lr.ctx_raw, "<<none>>") && rec->validating) { if (selabel_validate(rec, &spec->lr) < 0) { selinux_log(SELINUX_ERROR, "%s: context %s is invalid\n", path, spec->lr.ctx_raw); goto out; } } /* Process regex string */ rc = next_entry(&entry_len, mmap_area, sizeof(uint32_t)); if (rc < 0 || !entry_len) { rc = -1; goto out; } spec->regex_str = (char *)mmap_area->next_addr; rc = next_entry(NULL, mmap_area, entry_len); if (rc < 0) goto out; if (spec->regex_str[entry_len - 1] != '\0') { rc = -1; goto out; } /* Process mode */ if (version >= SELINUX_COMPILED_FCONTEXT_MODE) rc = next_entry(&mode, mmap_area, sizeof(uint32_t)); else rc = next_entry(&mode, mmap_area, sizeof(mode_t)); if (rc < 0) goto out; spec->mode = mode; /* map the stem id from the mmap file to the data->stem_arr */ rc = next_entry(&stem_id, mmap_area, sizeof(int32_t)); if (rc < 0) goto out; if (stem_id < 0 || stem_id >= (int32_t)stem_map_len) spec->stem_id = -1; else spec->stem_id = stem_map[stem_id]; /* retrieve the hasMetaChars bit */ rc = next_entry(&meta_chars, mmap_area, sizeof(uint32_t)); if (rc < 0) goto out; spec->hasMetaChars = meta_chars; /* and prefix length for use by selabel_lookup_best_match */ if (version >= SELINUX_COMPILED_FCONTEXT_PREFIX_LEN) { rc = next_entry(&prefix_len, mmap_area, sizeof(uint32_t)); if (rc < 0) goto out; spec->prefix_len = prefix_len; } rc = regex_load_mmap(mmap_area, &spec->regex, reg_arch_matches, &spec->regex_compiled); if (rc < 0) goto out; __pthread_mutex_init(&spec->regex_lock, NULL); data->nspec++; } rc = 0; out: free(stem_map); return rc; }